[
  {
    "path": ".gitattributes",
    "content": "docs/assets/*.jpg filter=lfs diff=lfs merge=lfs -text\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug.md",
    "content": "---\nname: Bug Report\nabout: Report a bug encountered while using this project\nlabels: bug\n---\n\n**What happened**:\n\n**What you expected to happen**:\n\n**How to reproduce it (as minimally and precisely as possible)**:\n\n**Anything else we need to know?**:\n\n**Environment**:\n\n- kubernetes-controller-sharding version: \n- Kubernetes version: \n- Others: \n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/enhancement.md",
    "content": "---\nname: Enhancement Request\nabout: Suggest an enhancement to this project\nlabels: enhancement\n---\n\n**What would you like to be added**:\n\n**Why is this needed**:\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "**What this PR does / why we need it**:\n\n**Which issue(s) this PR fixes**:\nFixes #\n\n**Special notes for your reviewer**:\n"
  },
  {
    "path": ".github/release.yaml",
    "content": "changelog:\n  exclude:\n    labels:\n    - no-release-note\n  categories:\n  - title: ⚠️ Breaking Changes\n    labels:\n    - breaking\n  - title: ✨ Features\n    labels:\n    - enhancement\n  - title: 🐛 Bug Fixes\n    labels:\n    - bug\n  - title: 📖 Documentation\n    labels:\n    - documentation\n  - title: 🧹 Cleanups\n    labels:\n    - cleanup\n  - title: 🤖 Dependencies\n    labels:\n    - dependencies\n  - title: ℹ️ Other Changes\n    labels:\n    - \"*\"\n"
  },
  {
    "path": ".github/renovate.json5",
    "content": "{\n  $schema: 'https://docs.renovatebot.com/renovate-schema.json',\n  extends: [\n    'config:recommended',\n    ':semanticCommitsDisabled',\n    'customManagers:githubActionsVersions',\n  ],\n  labels: [\n    'dependencies',\n  ],\n  postUpdateOptions: [\n    'gomodTidy',\n  ],\n  automergeStrategy: 'squash',\n  // required for automerging patch updates\n  separateMinorPatch: true,\n  kubernetes: {\n    managerFilePatterns: [\n      '/\\\\.yaml$/',\n    ],\n  },\n  customManagers: [\n    {\n      // generic detection for install manifests from GitHub releases\n      customType: 'regex',\n      managerFilePatterns: [\n        '/kustomization\\\\.yaml$/',\n      ],\n      matchStrings: [\n        'https://github\\\\.com/(?<depName>.*/.*?)/releases/download/(?<currentValue>.*?)/',\n      ],\n      datasourceTemplate: 'github-releases',\n    },\n    {\n      // generic detection for raw manifests from GitHub refs\n      customType: 'regex',\n      managerFilePatterns: [\n        '/kustomization\\\\.yaml$/',\n      ],\n      matchStrings: [\n        'https://raw.githubusercontent.com/(?<depName>.*?/.*?)/(?<currentValue>.*?)/',\n      ],\n      datasourceTemplate: 'github-releases',\n    },\n    {\n      // update `_VERSION` variables in Makefiles and scripts\n      // inspired by `regexManagers:dockerfileVersions` preset\n      customType: 'regex',\n      managerFilePatterns: [\n        '/Makefile$/',\n        '/\\\\.mk$/',\n        '/\\\\.sh$/',\n      ],\n      matchStrings: [\n        '# renovate: datasource=(?<datasource>[a-z-.]+?) depName=(?<depName>[^\\\\s]+?)(?: (lookupName|packageName)=(?<packageName>[^\\\\s]+?))?(?: versioning=(?<versioning>[^\\\\s]+?))?(?: extractVersion=(?<extractVersion>[^\\\\s]+?))?(?: registryUrl=(?<registryUrl>[^\\\\s]+?))?\\\\s.+?_VERSION *[?:]?= *\"?(?<currentValue>.+?)\"?\\\\s',\n      ],\n    },\n    {\n      // custom manager for updating kind node image tag and digest\n      customType: \"regex\",\n      managerFilePatterns: [\n        \"/^Makefile$/\",\n      ],\n      matchStrings: [\n        \"(?<depName>kindest/node):(?<currentValue>[^@]+)(?:@(?<currentDigest>[^\\\\s]+))?\",\n      ],\n      datasourceTemplate: \"docker\",\n    }\n  ],\n  packageRules: [\n    {\n      // disable update of dependency on the main module\n      matchPackageNames: [\n        'github.com/timebertt/kubernetes-controller-sharding',\n      ],\n      enabled: false,\n    },\n    {\n      // automerge non-major updates except 0.* versions\n      // similar to :automergeStableNonMajor preset, but also works for versioning schemes without range support\n      matchUpdateTypes: [\n        'minor',\n        'patch',\n      ],\n      matchCurrentVersion: '!/^v?0\\\\./',\n      automerge: true,\n    },\n    {\n      // automerge patch updates\n      matchUpdateTypes: [\n        'patch',\n      ],\n      automerge: true,\n    },\n    {\n      // automerge non-major golang.org/x updates\n      matchDatasources: [\n        'go',\n      ],\n      matchPackageNames: [\n        'golang.org/x/*',\n      ],\n      matchUpdateTypes: [\n        'minor',\n        'patch',\n        'digest',\n      ],\n      automerge: true,\n    },\n    {\n      // disable automerge for go minor updates\n      matchDatasources: [\n        'golang-version',\n      ],\n      matchUpdateTypes: [\n        'minor',\n      ],\n      automerge: false,\n    },\n    {\n      // bump k8s and controller-runtime go dependencies together\n      groupName: 'k8s packages',\n      groupSlug: 'k8s-go',\n      matchDatasources: [\n        'go',\n      ],\n      matchPackageNames: [\n        // from \"group:kubernetes\"\n        'k8s.io/api',\n        'k8s.io/apiextensions-apiserver',\n        'k8s.io/apimachinery',\n        'k8s.io/apiserver',\n        'k8s.io/cli-runtime',\n        'k8s.io/client-go',\n        'k8s.io/cloud-provider',\n        'k8s.io/cluster-bootstrap',\n        'k8s.io/code-generator',\n        'k8s.io/component-base',\n        'k8s.io/controller-manager',\n        'k8s.io/cri-api',\n        'k8s.io/csi-translation-lib',\n        'k8s.io/kube-aggregator',\n        'k8s.io/kube-controller-manager',\n        'k8s.io/kube-proxy',\n        'k8s.io/kube-scheduler',\n        'k8s.io/kubectl',\n        'k8s.io/kubelet',\n        'k8s.io/legacy-cloud-providers',\n        'k8s.io/metrics',\n        'k8s.io/mount-utils',\n        'k8s.io/pod-security-admission',\n        'k8s.io/sample-apiserver',\n        'k8s.io/sample-cli-plugin',\n        'k8s.io/sample-controller',\n        // added packages\n        'sigs.k8s.io/controller-runtime',\n      ],\n    },\n    {\n      // disable automerge for k8s minor updates\n      matchPackageNames: [\n        // datasource=go\n        'k8s.io/**', // includes more than the k8s-go group! (e.g., k8s.io/utils)\n        'sigs.k8s.io/controller-runtime',\n        // datasource=github-releases\n        'kubernetes/kubernetes',\n        'kubernetes-sigs/controller-tools',\n      ],\n      matchUpdateTypes: [\n        'minor',\n      ],\n      automerge: false,\n    },\n    {\n      // automerge k8s.io/utils updates\n      matchDatasources: [\n        'go',\n      ],\n      matchPackageNames: [\n        'k8s.io/utils',\n      ],\n      matchUpdateTypes: [\n        'digest',\n      ],\n      automerge: true,\n    },\n    {\n      // jsonpatch major version has to be kept in sync with k8s and controller-runtime dependencies\n      matchDatasources: [\n        'go',\n      ],\n      matchPackageNames: [\n        'gomodules.xyz/jsonpatch/*',\n      ],\n      matchUpdateTypes: [\n        'major',\n      ],\n      enabled: false,\n    },\n    {\n      // kind minor k8s version should be updated together with shoot k8s version\n      matchPackageNames: [\n        'kindest/node',\n      ],\n      matchUpdateTypes: [\n        'minor',\n      ],\n      enabled: false,\n    },\n    // don't add internal dependency updates to release notes\n    {\n      matchFileNames: [\n        'hack/config/**',\n        'hack/tools.mk',\n      ],\n      matchPackageNames: [\n        '!kubernetes-sigs/controller-tools',\n        '!ko-build/ko',\n      ],\n      addLabels: [\n        'no-release-note',\n      ],\n    },\n    {\n      matchDatasources: [\n        'go',\n      ],\n      matchPackageNames: [\n        'github.com/onsi/gomega',\n        'github.com/onsi/ginkgo/*',\n        'k8s.io/utils',\n      ],\n      addLabels: [\n        'no-release-note',\n      ],\n    },\n    {\n      // combine upgrade of manifests and image tag in one PR\n      groupName: 'external-dns',\n      matchPackageNames: [\n        '/external-dns/',\n      ],\n    },\n    {\n      // special case for ingress-nginx: version is prefixed with `controller-`\n      matchDatasources: [\n        'github-releases',\n      ],\n      matchPackageNames: [\n        'kubernetes/ingress-nginx',\n      ],\n      versionCompatibility: '^(?<compatibility>.*)-(?<version>.+)$',\n    },\n    {\n      // manual action required: upgrading kube-prometheus is not fully automated yet\n      matchDatasources: [\n        'github-releases',\n      ],\n      matchPackageNames: [\n        'prometheus-operator/kube-prometheus',\n      ],\n      prHeader: '⚠️ Manual action required ⚠️\\nPlease check this PR out and run `hack/config/monitoring/update.sh`.',\n    },\n    {\n      // kube-prometheus manifests are generated and managed by update.sh, disable renovate bumps\n      matchFileNames: [\n        'hack/config/monitoring/{crds,kube-prometheus}/**',\n      ],\n      enabled: false,\n    },\n    // help renovate fetch changelogs for packages that don't have any sourceUrl metadata attached\n    {\n      matchPackageNames: [\n        'registry.k8s.io/prometheus-adapter/prometheus-adapter',\n      ],\n      changelogUrl: 'https://github.com/kubernetes-sigs/prometheus-adapter',\n    },\n    {\n      matchPackageNames: [\n        'quay.io/brancz/kube-rbac-proxy',\n      ],\n      changelogUrl: 'https://github.com/brancz/kube-rbac-proxy',\n    },\n  ],\n}\n"
  },
  {
    "path": ".github/workflows/e2e.yaml",
    "content": "name: e2e\n\non:\n  push:\n    branches:\n    - main\n    tags:\n    - v*\n    paths-ignore:\n    - \"**.md\"\n  pull_request:\n\njobs:\n  e2e-kind:\n    runs-on: ubuntu-latest\n    env:\n      ARTIFACTS: artifacts\n\n    steps:\n    - uses: actions/checkout@v5\n    - uses: actions/setup-go@v6\n      with:\n        go-version-file: go.mod\n    - run: make ci-e2e-kind\n    - uses: actions/upload-artifact@v5\n      if: always()\n      with:\n        name: e2e-artifacts\n        path: artifacts\n        if-no-files-found: error\n"
  },
  {
    "path": ".github/workflows/images.yaml",
    "content": "name: images\n\non:\n  push:\n    branches:\n    - main\n    tags:\n    - v*\n  pull_request:\n\njobs:\n  images:\n    runs-on: ubuntu-latest\n    env:\n      # renovate: datasource=github-releases depName=ko-build/ko\n      KO_VERSION: v0.18.1\n    steps:\n    - uses: actions/checkout@v5\n      with:\n        # fetch all history so that git describe works (needed by hack/prepare-image-metadata.sh)\n        fetch-depth: 0\n    - uses: actions/setup-go@v6\n      with:\n        go-version-file: go.mod\n    - uses: ko-build/setup-ko@v0.9\n      with:\n        version: ${{ env.KO_VERSION }}\n    - name: Prepare image metadata\n      id: meta\n      run: ./hack/prepare-image-metadata.sh\n    - name: ko build\n      run: |\n        set -ex\n\n        # prepare .ko.yaml to inject build settings into all images\n        entrypoints=(\n          ./cmd/sharder\n          ./cmd/checksum-controller\n          ./webhosting-operator/cmd/experiment\n          ./webhosting-operator/cmd/webhosting-operator\n        )\n        \n        echo builds: > .ko.yaml\n        for entrypoint in \"${entrypoints[@]}\" ; do\n        cat >> .ko.yaml <<EOF\n        - main: $entrypoint\n          ldflags:\n          - |\n            {{.Env.LDFLAGS}}\n        EOF\n        done\n\n        ko build --push=${{ github.event_name != 'pull_request' }} --sbom none --base-import-paths \\\n          --tags \"${{ steps.meta.outputs.tags }}\" --image-label \"${{ steps.meta.outputs.labels }}\" \\\n          --platform linux/amd64,linux/arm64 \\\n          \"${entrypoints[@]}\"\n"
  },
  {
    "path": ".github/workflows/release-notes.yaml",
    "content": "name: release-notes\n\non:\n  push:\n    branches:\n    - main\n  workflow_dispatch: {}\n\njobs:\n  release-notes:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v5\n    - name: Draft release notes\n      run: |\n        set -o errexit\n        set -o nounset\n        set -o pipefail\n        set -x\n        \n        latest_tag=\"$(gh release view --json tagName --jq .tagName)\"\n        \n        major=\"$(echo \"$latest_tag\" | cut -d. -f1)\"\n        minor=\"$(echo \"$latest_tag\" | cut -d. -f2)\"\n        new_tag=\"$major.$((minor+1)).0\"\n        \n        if [ \"$(gh release view \"$new_tag\" --json isDraft --jq .isDraft)\" = true ] ; then\n          # clean up previous draft release\n          gh release delete -y \"$new_tag\"\n        fi\n        \n        gh release create \"$new_tag\" --draft --generate-notes --notes-start-tag=\"${latest_tag%.*}.0\"\n      env:\n        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/renovate.yaml",
    "content": "name: renovate\n\non:\n  push:\n    branches:\n    - renovate/*\n\njobs:\n  post-update:\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v5\n      with:\n        token: ${{ secrets.RENOVATE_TOKEN }}\n    - uses: actions/setup-go@v6\n      with:\n        go-version-file: go.mod\n\n    # prevent triggering infinite loop of this action\n    - name: safety check\n      id: safety\n      run: |\n        if git log -1 --pretty=full | grep '\\[skip renovate-post-update\\]' >/dev/null ; then\n          echo \"Skipping renovate post update workflow\"\n          echo \"skip=true\" >> $GITHUB_OUTPUT\n        fi\n\n    # Some dependency updates might require updating go.work.sum.\n    # Automatically run `make tidy` on renovate branches as long as renovate doesn't know how to handle go workspaces.\n    # Some dependency updates might require re-running code generation.\n    # Run `make generate` and commit all changes if any.\n    - run: make tidy generate\n      if: steps.safety.outputs.skip != 'true'\n    - uses: stefanzweifel/git-auto-commit-action@v7\n      if: steps.safety.outputs.skip != 'true'\n      with:\n        commit_message: |\n          make tidy generate\n          \n          [skip renovate-post-update]\n\n        # commit with renovate's user, so that it doesn't block further updates to the PR\n        commit_user_name: renovate[bot]\n        commit_user_email: 29139614+renovate[bot]@users.noreply.github.com\n        commit_author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>\n"
  },
  {
    "path": ".github/workflows/verify.yaml",
    "content": "name: verify\n\non:\n  push:\n    branches:\n    - main\n    tags:\n    - v*\n  pull_request:\n\njobs:\n  verify:\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v5\n    - uses: actions/setup-go@v6\n      with:\n        go-version-file: go.mod\n    - run: make verify\n"
  },
  {
    "path": ".gitignore",
    "content": "*.secret*\n.envrc\nhack/kind_kubeconfig.yaml\n.gitguardian.yaml\n.ko.yaml\n\n# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\nbin\ntestbin/*\n\n# Test binary, build with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# editor and IDE settings\n.idea\n.vscode\n*.swp\n*.swo\n*~\n"
  },
  {
    "path": ".golangci.yaml",
    "content": "version: \"2\"\n\nrun:\n  concurrency: 4\n\nlinters:\n  enable:\n  - copyloopvar\n  - ginkgolinter\n  - gocritic\n  - gosec\n  - importas\n  - misspell\n  - nilerr\n  - nolintlint\n  - prealloc\n  - revive\n  - staticcheck\n  - unconvert\n  - unparam\n  - whitespace\n\n  settings:\n    importas:\n      alias:\n      - pkg: github.com/timebertt/kubernetes-controller-sharding/apis/(\\w+)/(v[\\w\\d]+)\n        alias: $1$2\n      - pkg: github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/apis/(\\w+)/(v[\\w\\d]+)\n        alias: $1$2\n      - pkg: k8s.io/api/(\\w+)/(v[\\w\\d]+)\n        alias: $1$2\n      - pkg: k8s.io/apimachinery/pkg/apis/(\\w+)/(v[\\w\\d]+)\n        alias: $1$2\n      - pkg: k8s.io/apimachinery/pkg/api/([^m]\\w+)\n        alias: api${1}\n      - pkg: k8s.io/apimachinery/pkg/util/(\\w+)\n        alias: util${1}\n      - pkg: k8s.io/client-go/tools/clientcmd/api/(\\w+)\n        alias: clientcmd${1}\n      - pkg: k8s.io/client-go/tools/cache\n        alias: toolscache\n      - pkg: k8s.io/component-base/config/(v[\\w\\d]+)\n        alias: componentbaseconfig$1\n      - pkg: k8s.io/utils/clock/testing\n        alias: testclock\n      - pkg: sigs.k8s.io/controller-runtime/pkg/client/fake\n        alias: fakeclient\n      - pkg: sigs.k8s.io/controller-runtime/pkg/log/zap\n        alias: logzap\n      - pkg: sigs.k8s.io/controller-runtime/pkg/log\n        alias: logf\n    misspell:\n      locale: US\n    nolintlint:\n      require-specific: true\n    revive:\n      rules:\n      - name: context-as-argument\n      - name: duplicated-imports\n      - name: early-return\n      - name: exported\n      - name: unreachable-code\n\n  exclusions:\n    generated: strict\n\n    presets:\n    - comments\n    - common-false-positives\n    - std-error-handling\n\n    rules:\n    - linters:\n      - staticcheck\n      path: pkg/utils/test\n      text: 'ST1001: should not use dot imports'\n    - linters:\n      - nolintlint\n      text: should be written without leading space\n"
  },
  {
    "path": ".run/experiment (kind).run.xml",
    "content": "<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"experiment (kind)\" type=\"GoApplicationRunConfiguration\" factoryName=\"Go Application\">\n    <module name=\"kubernetes-controller-sharding\" />\n    <working_directory value=\"$PROJECT_DIR$/webhosting-operator\" />\n    <parameters value=\"basic\" />\n    <envs>\n      <env name=\"KUBECONFIG\" value=\"$PROJECT_DIR$/hack/kind_kubeconfig.yaml\" />\n    </envs>\n    <kind value=\"PACKAGE\" />\n    <package value=\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/cmd/experiment\" />\n    <directory value=\"$PROJECT_DIR$\" />\n    <filePath value=\"$PROJECT_DIR$/webhosting-operator/cmd/experiment/main.go\" />\n    <method v=\"2\" />\n  </configuration>\n</component>"
  },
  {
    "path": ".run/shard (kind).run.xml",
    "content": "<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"checksum-controller (kind)\" type=\"GoApplicationRunConfiguration\" factoryName=\"Go Application\">\n    <module name=\"kubernetes-controller-sharding\" />\n    <working_directory value=\"$PROJECT_DIR$\" />\n    <parameters value=\"--zap-devel --shard-name=checksum-controller-host --lease-namespace=default\" />\n    <envs>\n      <env name=\"KUBECONFIG\" value=\"$PROJECT_DIR$/hack/kind_kubeconfig.yaml\" />\n    </envs>\n    <kind value=\"PACKAGE\" />\n    <package value=\"github.com/timebertt/kubernetes-controller-sharding/cmd/checksum-controller\" />\n    <directory value=\"$PROJECT_DIR$\" />\n    <filePath value=\"$PROJECT_DIR$/webhosting-operator/cmd/experiment/main.go\" />\n    <method v=\"2\" />\n  </configuration>\n</component>\n"
  },
  {
    "path": ".run/sharder (kind).run.xml",
    "content": "<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"sharder (kind)\" type=\"GoApplicationRunConfiguration\" factoryName=\"Go Application\">\n    <module name=\"kubernetes-controller-sharding\" />\n    <working_directory value=\"$PROJECT_DIR$\" />\n    <parameters value=\"--config=hack/config/sharder/host/config.yaml --zap-devel\" />\n    <envs>\n      <env name=\"LEADER_ELECT\" value=\"false\" />\n      <env name=\"KUBECONFIG\" value=\"$PROJECT_DIR$/hack/kind_kubeconfig.yaml\" />\n    </envs>\n    <kind value=\"PACKAGE\" />\n    <package value=\"github.com/timebertt/kubernetes-controller-sharding/cmd/sharder\" />\n    <directory value=\"$PROJECT_DIR$\" />\n    <filePath value=\"$PROJECT_DIR$/webhosting-operator/cmd/experiment/main.go\" />\n    <method v=\"2\" />\n  </configuration>\n</component>\n"
  },
  {
    "path": ".run/webhosting-operator (kind).run.xml",
    "content": "<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"webhosting-operator (kind)\" type=\"GoApplicationRunConfiguration\" factoryName=\"Go Application\">\n    <module name=\"kubernetes-controller-sharding\" />\n    <working_directory value=\"$PROJECT_DIR$/webhosting-operator\" />\n    <envs>\n      <env name=\"ENABLE_SHARDING\" value=\"true\" />\n      <env name=\"KUBECONFIG\" value=\"$PROJECT_DIR$/hack/kind_kubeconfig.yaml\" />\n    </envs>\n    <kind value=\"PACKAGE\" />\n    <package value=\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/cmd/webhosting-operator\" />\n    <directory value=\"$PROJECT_DIR$\" />\n    <filePath value=\"$PROJECT_DIR$/webhosting-operator/main.go\" />\n    <method v=\"2\" />\n  </configuration>\n</component>\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "Makefile",
    "content": "PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))\n\n# Image URL to use all building/pushing image targets\nTAG ?= latest\nGHCR_REPO ?= ghcr.io/timebertt/kubernetes-controller-sharding\nSHARDER_IMG ?= $(GHCR_REPO)/sharder:$(TAG)\nCHECKSUM_CONTROLLER_IMG ?= $(GHCR_REPO)/checksum-controller:$(TAG)\nWEBHOSTING_OPERATOR_IMG ?= $(GHCR_REPO)/webhosting-operator:$(TAG)\nEXPERIMENT_IMG ?= $(GHCR_REPO)/experiment:$(TAG)\n\n# Optionally, overwrite the envtest version or assets directory to use\nENVTEST_K8S_VERSION =\nKUBEBUILDER_ASSETS =\n\n# Setting SHELL to bash allows bash commands to be executed by recipes.\n# Options are set to exit when a recipe line exits non-zero or a piped command fails.\nSHELL = /usr/bin/env bash -o pipefail\n.SHELLFLAGS = -ec\n\n.PHONY: all\nall: build\n\n##@ General\n\n# The help target prints out all targets with their descriptions organized\n# beneath their categories. The categories are represented by '##@' and the\n# target descriptions by '##'. The awk commands is responsible for reading the\n# entire set of makefiles included in this invocation, looking for lines of the\n# file as xyz: ## something, and then pretty-format the target and help. Then,\n# if there's a line with ##@ something, that gets pretty-printed as a category.\n# More info on the usage of ANSI control characters for terminal formatting:\n# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters\n# More info on the awk command:\n# http://linuxcommand.org/lc3_adv_awk.php\n\n.PHONY: help\nhelp: ## Display this help.\n\t@awk 'BEGIN {FS = \":.*##\"; printf \"\\nUsage:\\n  make \\033[36m<target>\\033[0m\\n\"} /^[a-zA-Z_0-9-]+:.*?##/ { printf \"  \\033[36m%-15s\\033[0m %s\\n\", $$1, $$2 } /^##@/ { printf \"\\n\\033[1m%s\\033[0m\\n\", substr($$0, 5) } ' $(MAKEFILE_LIST)\n\n##@ Tools\n\ninclude hack/tools.mk\n\n.PHONY: clean-tools-bin\nclean-tools-bin: ## Empty the tools binary directory.\n\trm -rf $(TOOLS_BIN_DIR)/*\n\n##@ Development\n\n.PHONY: tidy\ntidy: ## Runs go mod to ensure modules are up to date.\n\tgo mod tidy\n\tcd webhosting-operator && go mod tidy\n\t@# regenerate go.work.sum\n\trm -f go.work.sum\n\tgo mod download\n\n.PHONY: generate-fast\ngenerate-fast: $(CONTROLLER_GEN) tidy ## Run all fast code generators for the main module.\n\t$(CONTROLLER_GEN) rbac:roleName=sharder crd paths=\"./pkg/...\" output:rbac:artifacts:config=config/rbac output:crd:artifacts:config=config/crds\n\t$(CONTROLLER_GEN) object:headerFile=\"hack/boilerplate.go.txt\" paths=\"./pkg/...\"\n\n.PHONY: generate-fast-webhosting\ngenerate-fast-webhosting: $(CONTROLLER_GEN) tidy ## Run all fast code generators for the webhosting-operator module.\n\t$(CONTROLLER_GEN) rbac:roleName=operator crd paths=\"./webhosting-operator/...\" output:rbac:artifacts:config=webhosting-operator/config/manager/rbac output:crd:artifacts:config=webhosting-operator/config/manager/crds\n\t$(CONTROLLER_GEN) object:headerFile=\"hack/boilerplate.go.txt\" paths=\"./webhosting-operator/...\"\n\n.PHONY: generate\ngenerate: $(VGOPATH) generate-fast generate-fast-webhosting tidy ## Run all code generators.\n\thack/update-codegen.sh\n\n.PHONY: fmt\nfmt: ## Run go fmt against code.\n\tgo fmt ./...\n\tcd webhosting-operator && go fmt ./...\n\n.PHONY: test\ntest: ## Run unit tests.\n\t./hack/test.sh ./cmd/... ./pkg/... ./webhosting-operator/pkg/...\n\n.PHONY: test-integration\ntest-integration: $(SETUP_ENVTEST) ## Run integration tests.\n\t./hack/test-integration.sh ./test/integration/...\n\n.PHONY: test-e2e\ntest-e2e: $(GINKGO) ## Run e2e tests.\n\t./hack/test-e2e.sh $(GINKGO_FLAGS) ./test/e2e/... ./webhosting-operator/test/e2e/...\n\n.PHONY: skaffold-fix\nskaffold-fix: $(SKAFFOLD) ## Upgrade skaffold configuration to the latest apiVersion.\n\t$(SKAFFOLD) fix --overwrite\n\t[ ! -f $(SKAFFOLD_FILENAME).v2 ] || rm $(SKAFFOLD_FILENAME).v2\n\n##@ Verification\n\n.PHONY: lint\nlint: $(GOLANGCI_LINT) ## Run golangci-lint against code.\n\t$(GOLANGCI_LINT) run ./... ./webhosting-operator/...\n\n.PHONY: check\ncheck: lint test test-integration ## Check everything (lint + test + test-integration).\n\n.PHONY: verify-fmt\nverify-fmt: fmt ## Verify go code is formatted.\n\t@if !(git diff --quiet HEAD); then \\\n\t\techo \"unformatted files detected, please run 'make fmt'\"; exit 1; \\\n\tfi\n\n.PHONY: verify-generate\nverify-generate: generate ## Verify generated files are up to date.\n\t@if !(git diff --quiet HEAD); then \\\n\t\techo \"generated files are out of date, please run 'make generate'\"; exit 1; \\\n\tfi\n\n.PHONY: verify-tidy\nverify-tidy: tidy ## Verify go module files are up to date.\n\t@if !(git diff --quiet HEAD -- go.work.sum go.{mod,sum} webhosting-operator/go.{mod,sum}); then \\\n\t\techo \"go module files are out of date, please run 'make tidy'\"; exit 1; \\\n\tfi\n\n.PHONY: verify\nverify: verify-tidy verify-fmt verify-generate check ## Verify everything (all verify-* rules + check).\n\n.PHONY: ci-e2e-kind\nci-e2e-kind: $(KIND)\n\t./hack/ci-e2e-kind.sh\n\n##@ Build\n\n.PHONY: build\nbuild: ## Build the sharder binary.\n\tgo build -o bin/sharder ./cmd/sharder\n\n.PHONY: run\nrun: $(KUBECTL) generate-fast ## Run the sharder from your host and deploy prerequisites.\n\t$(MAKE) deploy SKAFFOLD_MODULE=cert-manager\n\t$(KUBECTL) apply --server-side --force-conflicts -k config/crds\n\t$(KUBECTL) apply --server-side --force-conflicts -k hack/config/certificates/host\n\tgo run ./cmd/sharder --config=hack/config/sharder/host/config.yaml --zap-devel\n\nSHARD_NAME ?= checksum-controller-$(shell tr -dc bcdfghjklmnpqrstvwxz2456789 </dev/urandom | head -c 8)\n\n.PHONY: run-checksum-controller\nrun-checksum-controller: $(KUBECTL) ## Run checksum-controller from your host and deploy prerequisites.\n\t$(KUBECTL) apply --server-side --force-conflicts -k hack/config/checksum-controller/controllerring\n\tgo run ./cmd/checksum-controller --shard-name=$(SHARD_NAME) --lease-namespace=default --zap-devel\n\nPUSH ?= false\nimages: export KO_DOCKER_REPO = $(GHCR_REPO)\n\n.PHONY: images\nimages: $(KO) ## Build and push container images using ko.\n\t$(KO) build --push=$(PUSH) --sbom none --base-import-paths -t $(TAG) --platform linux/amd64,linux/arm64 \\\n\t\t./cmd/sharder ./cmd/checksum-controller ./webhosting-operator/cmd/webhosting-operator\n\n##@ Deployment\n\nKIND_KUBECONFIG := $(PROJECT_DIR)/hack/kind_kubeconfig.yaml\nkind-up kind-down: export KUBECONFIG = $(KIND_KUBECONFIG)\n\n.PHONY: kind-up\nkind-up: $(KIND) $(KUBECTL) ## Launch a kind cluster for local development and testing.\n\t$(KIND) create cluster --name sharding --config hack/config/kind-config.yaml --image kindest/node:v1.33.7@sha256:d26ef333bdb2cbe9862a0f7c3803ecc7b4303d8cea8e814b481b09949d353040\n\t# workaround https://kind.sigs.k8s.io/docs/user/known-issues/#pod-errors-due-to-too-many-open-files\n\t$(KUBECTL) get nodes -o name | cut -d/ -f2 | xargs -I {} docker exec {} sh -c \"sysctl fs.inotify.max_user_instances=8192\"\n\t# run `export KUBECONFIG=$$PWD/hack/kind_kubeconfig.yaml` to target the created kind cluster.\n\n.PHONY: kind-down\nkind-down: $(KIND) ## Tear down the kind testing cluster.\n\t$(KIND) delete cluster --name sharding\n\nexport SKAFFOLD_FILENAME = hack/config/skaffold.yaml\n# use static label for skaffold to prevent rolling all components on every skaffold invocation\ndeploy up dev down: export SKAFFOLD_LABEL = skaffold.dev/run-id=sharding\n# use dedicated ghcr repo for dev images to prevent spamming the \"production\" image repo\nup dev: export SKAFFOLD_DEFAULT_REPO ?= ghcr.io/timebertt/dev-images\nup dev: export SKAFFOLD_TAIL ?= true\n\n.PHONY: deploy\ndeploy: $(SKAFFOLD) $(KUBECTL) $(YQ) ## Build all images and deploy everything to K8s cluster specified in $KUBECONFIG.\n\t$(SKAFFOLD) deploy -i $(SHARDER_IMG) -i $(CHECKSUM_CONTROLLER_IMG) -i $(WEBHOSTING_OPERATOR_IMG) -i $(EXPERIMENT_IMG)\n\n.PHONY: up\nup: $(SKAFFOLD) $(KUBECTL) $(YQ) ## Build all images, deploy everything to K8s cluster specified in $KUBECONFIG, start port-forward and tail logs.\n\t$(SKAFFOLD) run\n\n.PHONY: dev\ndev: $(SKAFFOLD) $(KUBECTL) $(YQ) ## Start continuous dev loop with skaffold.\n\t$(SKAFFOLD) dev --port-forward=user --cleanup=false --trigger=manual\n\n.PHONY: down\ndown: $(SKAFFOLD) $(KUBECTL) $(YQ) ## Remove everything from K8s cluster specified in $KUBECONFIG.\n\t$(SKAFFOLD) delete\n"
  },
  {
    "path": "README.md",
    "content": "# Kubernetes Controller Sharding\n\n_Horizontally Scalable Kubernetes Controllers_ 🚀\n\n## TL;DR 📖\n\nMake Kubernetes controllers horizontally scalable by distributing reconciliation of API objects across multiple controller instances.\nRemove the limitation to have only a single active replica (leader) per controller.\n\nSee [Getting Started With Controller Sharding](docs/getting-started.md) for a quick start with this project.\n\nI presented this project at KubeCon Europe 2025 London ([recording](https://youtu.be/OTzd9eTtLRA)) and ContainerDays 2025 Hamburg ([recording](https://youtu.be/SEy-Z00SSpM)).\nCheck out the recordings for a 30-minute overview with demos!\n\n## About ℹ️\n\nI started this project as part of my Master's studies in Computer Science at the [DHBW Center for Advanced Studies](https://www.cas.dhbw.de/) (CAS).\nI completed a study project (\"half-time thesis\") on this topic and evolved it in my Master's thesis.\n\n- Download and read the study project (first paper) here: [thesis-controller-sharding](https://github.com/timebertt/thesis-controller-sharding)\n- Download and read the Master's thesis (second paper) here: [masters-thesis-controller-sharding](https://github.com/timebertt/masters-thesis-controller-sharding)\n\nThis repository contains the implementation belonging to the scientific work: the actual sharding implementation, a sample operator using controller sharding, a monitoring and continuous profiling setup, and some tools for development and evaluation purposes.\n\nSince finishing the scientific work, this project evolved further, especially in the [v0.9 release](https://github.com/timebertt/kubernetes-controller-sharding/releases/tag/v0.9.0).\nBe aware that the Master's thesis might not reflect the current development state in all descriptions.\n\n## Motivation 💡\n\nTypically, [Kubernetes controllers](https://kubernetes.io/docs/concepts/architecture/controller/) use a leader election mechanism to determine a *single* active controller instance (leader).\nWhen deploying multiple instances of the same controller, there will only be one active instance at any given time, other instances will be on standby.\nThis is done to prevent multiple controller instances from performing uncoordinated and conflicting actions (reconciliations) on a single object concurrently.\n\nIf the current leader goes down and loses leadership (e.g. network failure, rolling update) another instance takes over leadership and becomes the active instance.\nSuch a setup can be described as an \"active-passive HA setup\". It minimizes \"controller downtime\" and facilitates fast fail-overs.\nHowever, it cannot be considered as \"horizontal scaling\" as work is not distributed among multiple instances.\n\nThis restriction imposes scalability limitations for Kubernetes controllers.\nI.e., the rate of reconciliations, amount of objects, etc. is limited by the machine size that the active controller runs on and the network bandwidth it can use.\nIn contrast to usual stateless applications, one cannot increase the throughput of the system by adding more instances (scaling horizontally) but only by using bigger instances (scaling vertically).\n\n## Introduction 🚀\n\nThis project allows scaling Kubernetes controllers horizontally by removing the restriction of having only one active replica per controller (allows active-active setups).\nIt distributes reconciliation of Kubernetes objects across multiple controller instances, while still ensuring that only a single controller instance acts on a single object at any given time.\nFor this, the project applies proven sharding mechanisms used in distributed databases to Kubernetes controllers.\n\nThe project introduces a `sharder` component that implements sharding in a generic way and can be applied to any Kubernetes controller (independent of the used programming language and controller framework).\nThe `sharder` component is installed into the cluster along with a `ControllerRing` custom resource.\nA `ControllerRing` declares a virtual ring of sharded controller instances and specifies API resources that should be distributed across shards in the ring.\nIt configures sharding on the cluster-scope level (i.e., objects in all namespaces), hence the `ControllerRing` name.\n\nThe watch cache is an expensive part of a controller regarding network transfer, CPU (decoding), and memory (local copy of all objects).\nWhen running multiple instances of a controller, the individual instances must thus only watch the subset of objects they are responsible for.\nOtherwise, the setup would only multiply the resource consumption.\nThe sharder assigns objects to instances via the shard label.\nEach shard then uses a label selector with its own instance name to watch only the objects that are assigned to it.\n\nAlongside the actual sharding implementation, this project contains a setup for simple [development, testing](docs/development.md), and [evaluation](docs/evaluation.md) of the sharding mechanism.\nThis includes an example operator that uses controller sharding ([webhosting-operator](webhosting-operator)).\nSee [Getting Started With Controller Sharding](docs/getting-started.md) for more details.\n\nTo support sharding in your Kubernetes controller, only three aspects need to be implemented:\n\n- announce ring membership and shard health: maintain individual shard `Leases` instead of performing leader election on a single `Lease`\n- only watch, cache, and reconcile objects assigned to the respective shard: add a shard-specific label selector to watches\n- acknowledge object movements during rebalancing: remove the drain and shard label when the drain label is set and stop reconciling the object\n\nSee [Implement Sharding in Your Controller](docs/implement-sharding.md) for more information and examples.\n\n## Design 📐\n\n![Sharding Architecture](docs/assets/architecture.svg)\n\nSee [Design](docs/design.md) for more details on the sharding architecture and design decisions.\n\n## Discussion 💬\n\nFeel free to contact me on [LinkedIn](https://www.linkedin.com/in/timebertt/) or the [Kubernetes Slack](https://kubernetes.slack.com/) ([get an invitation](https://slack.k8s.io/)): [@timebertt](https://kubernetes.slack.com/team/UF8C35Z0D).\n"
  },
  {
    "path": "cmd/checksum-controller/main.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage main\n\nimport (\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n\t\"go.uber.org/zap/zapcore\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\t\"k8s.io/apimachinery/pkg/util/rand\"\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/cache\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client/config\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager/signals\"\n\tmetricsserver \"sigs.k8s.io/controller-runtime/pkg/metrics/server\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\tshardlease \"github.com/timebertt/kubernetes-controller-sharding/pkg/shard/lease\"\n)\n\nfunc main() {\n\trand.Seed(time.Now().UnixNano())\n\topts := newOptions()\n\n\tcmd := &cobra.Command{\n\t\tUse:   \"checksum-controller\",\n\t\tShort: \"Run an example sharded controller\",\n\t\tLong: `The checksum-controller is an example for implementing the controller requirements for sharding.\nFor this, it creates a shard Lease object and renews it periodically.\nIt also starts a controller for Secrets that are assigned to the shard and handles the drain operation as expected.\nSee https://github.com/timebertt/kubernetes-controller-sharding/blob/main/docs/implement-sharding.md for more details.\nThis example sharded controller is also useful for developing the sharding components.`,\n\n\t\tArgs:          cobra.NoArgs,\n\t\tSilenceErrors: true,\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\tif err := opts.validate(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tcmd.SilenceUsage = true\n\n\t\t\treturn opts.run(cmd.Context())\n\t\t},\n\t}\n\n\topts.AddFlags(cmd.Flags())\n\n\tif err := cmd.ExecuteContext(signals.SetupSignalHandler()); err != nil {\n\t\tfmt.Println(err)\n\t\tos.Exit(1)\n\t}\n}\n\ntype options struct {\n\tzapOptions         *zap.Options\n\tcontrollerRingName string\n\tnamespace          string\n\tleaseNamespace     string\n\tshardName          string\n}\n\nfunc newOptions() *options {\n\treturn &options{\n\t\tzapOptions: &zap.Options{\n\t\t\tTimeEncoder: zapcore.ISO8601TimeEncoder,\n\t\t},\n\n\t\tcontrollerRingName: \"checksum-controller\",\n\t\tnamespace:          metav1.NamespaceDefault,\n\t}\n}\n\nfunc (o *options) AddFlags(fs *pflag.FlagSet) {\n\tfs.StringVar(&o.controllerRingName, \"controllerring\", o.controllerRingName, \"Name of the ControllerRing the shard belongs to.\")\n\tfs.StringVar(&o.namespace, \"namespace\", o.namespace, \"Namespace to watch objects in.\")\n\tfs.StringVar(&o.leaseNamespace, \"lease-namespace\", o.leaseNamespace, \"Namespace to use for the shard lease. Defaults to the pod's namespace if running in-cluster.\")\n\tfs.StringVar(&o.shardName, \"shard-name\", o.shardName, \"Name of the shard. Defaults to the instance's hostname.\")\n\n\tzapFlagSet := flag.NewFlagSet(\"zap\", flag.ContinueOnError)\n\to.zapOptions.BindFlags(zapFlagSet)\n\tfs.AddGoFlagSet(zapFlagSet)\n}\n\nfunc (o *options) validate() error {\n\tif o.controllerRingName == \"\" {\n\t\treturn fmt.Errorf(\"--controllerring must not be empty\")\n\t}\n\n\treturn nil\n}\n\nfunc (o *options) run(ctx context.Context) error {\n\tlog := zap.New(zap.UseFlagOptions(o.zapOptions))\n\tlogf.SetLogger(log)\n\tklog.SetLogger(log)\n\n\tlog.Info(\"Getting rest config\")\n\trestConfig, err := config.GetConfig()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed getting rest config: %w\", err)\n\t}\n\n\tlog.Info(\"Setting up shard lease\")\n\tshardLease, err := shardlease.NewResourceLock(restConfig, shardlease.Options{\n\t\tControllerRingName: o.controllerRingName,\n\t\tLeaseNamespace:     o.leaseNamespace, // optional, can be empty\n\t\tShardName:          o.shardName,      // optional, can be empty\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed creating shard lease: %w\", err)\n\t}\n\n\tlog.Info(\"Setting up manager\")\n\tmgr, err := manager.New(restConfig, manager.Options{\n\t\tMetrics: metricsserver.Options{\n\t\t\tBindAddress: \"0\",\n\t\t},\n\t\tHealthProbeBindAddress: \"0\",\n\n\t\tGracefulShutdownTimeout: ptr.To(5 * time.Second),\n\n\t\t// SHARD LEASE\n\t\t// Use manager's leader election mechanism for maintaining the shard lease.\n\t\t// With this, controllers will only run as long as manager holds the shard lease.\n\t\t// After graceful termination, the shard lease will be released.\n\t\tLeaderElection:                      true,\n\t\tLeaderElectionResourceLockInterface: shardLease,\n\t\tLeaderElectionReleaseOnCancel:       true,\n\n\t\t// FILTERED WATCH CACHE\n\t\tCache: cache.Options{\n\t\t\t// This controller only acts on objects in a single configured namespace.\n\t\t\tDefaultNamespaces: map[string]cache.Config{o.namespace: {}},\n\t\t\t// Configure cache to only watch objects that are assigned to this shard.\n\t\t\t// This controller only watches sharded objects, so we can configure the label selector on the cache's global level.\n\t\t\t// If your controller watches sharded objects as well as non-sharded objects, use cache.Options.ByObject to configure\n\t\t\t// the label selector on object level.\n\t\t\tDefaultLabelSelector: labels.SelectorFromSet(labels.Set{\n\t\t\t\tshardingv1alpha1.LabelShard(o.controllerRingName): shardLease.Identity(),\n\t\t\t}),\n\t\t},\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed setting up manager: %w\", err)\n\t}\n\n\tlog.Info(\"Setting up controller\")\n\tif err := (&Reconciler{}).AddToManager(mgr, o.controllerRingName, shardLease.Identity()); err != nil {\n\t\treturn fmt.Errorf(\"failed adding controller: %w\", err)\n\t}\n\n\tlog.Info(\"Starting manager\")\n\tmanagerDone := make(chan error, 1)\n\tmanagerCtx, managerCancel := context.WithCancel(context.Background())\n\n\tgo func() {\n\t\tmanagerDone <- mgr.Start(managerCtx)\n\t}()\n\n\t// Usually, SIGINT and SIGTERM trigger graceful termination immediately.\n\t// For development purposes, we allow simulating non-graceful termination by delaying cancellation of the manager.\n\t<-ctx.Done()\n\tlog.Info(\"Shutting down gracefully in 2 seconds, send another SIGINT or SIGTERM to shut down non-gracefully\")\n\n\t<-time.After(2 * time.Second)\n\n\t// signal manager to shut down, wait for it to terminate, and propagate the error it returned\n\tmanagerCancel()\n\treturn <-managerDone\n}\n"
  },
  {
    "path": "cmd/checksum-controller/reconciler.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage main\n\nimport (\n\t\"context\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"maps\"\n\n\tcorev1 \"k8s.io/api/core/v1\"\n\tapiequality \"k8s.io/apimachinery/pkg/api/equality\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/builder\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil\"\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tshardcontroller \"github.com/timebertt/kubernetes-controller-sharding/pkg/shard/controller\"\n)\n\n// Reconciler watches Secrets and creates a ConfigMap for every Secret containing the Secret data's checksums.\n// It handles the shard and drain label.\ntype Reconciler struct {\n\tClient client.Client\n}\n\n// AddToManager adds Reconciler to the given manager.\nfunc (r *Reconciler) AddToManager(mgr manager.Manager, controllerRingName, shardName string) error {\n\tif r.Client == nil {\n\t\tr.Client = mgr.GetClient()\n\t}\n\n\t// ACKNOWLEDGE DRAIN OPERATIONS\n\t// Use the shardcontroller package as helpers for:\n\t// - a predicate that triggers when the drain label is present (even if the actual predicates don't trigger)\n\t// - wrapping the actual reconciler a reconciler that handles the drain operation for us\n\treturn builder.ControllerManagedBy(mgr).\n\t\tNamed(\"secret-checksums\").\n\t\tFor(&corev1.Secret{}, builder.WithPredicates(shardcontroller.Predicate(controllerRingName, shardName, SecretDataChanged()))).\n\t\tOwns(&corev1.ConfigMap{}, builder.WithPredicates(ObjectDeleted())).\n\t\tWithOptions(controller.Options{\n\t\t\tMaxConcurrentReconciles: 5,\n\t\t}).\n\t\tComplete(\n\t\t\tshardcontroller.NewShardedReconciler(mgr).\n\t\t\t\tFor(&corev1.Secret{}).\n\t\t\t\tInControllerRing(controllerRingName).\n\t\t\t\tWithShardName(shardName).\n\t\t\t\tMustBuild(r),\n\t\t)\n}\n\n// SecretDataChanged returns a predicate that is similar to predicate.GenerationChangedPredicate but for Secrets\n// that don't have a metadata.generation field.\nfunc SecretDataChanged() predicate.Predicate {\n\treturn predicate.Funcs{\n\t\tUpdateFunc: func(e event.UpdateEvent) bool {\n\t\t\treturn apiequality.Semantic.DeepEqual(e.ObjectOld.(*corev1.Secret).Data, e.ObjectNew.(*corev1.Secret).Data)\n\t\t},\n\t}\n}\n\n// ObjectDeleted returns a predicate that only triggers for DELETE events.\nfunc ObjectDeleted() predicate.Predicate {\n\treturn predicate.Funcs{\n\t\tCreateFunc:  func(_ event.CreateEvent) bool { return false },\n\t\tUpdateFunc:  func(_ event.UpdateEvent) bool { return false },\n\t\tDeleteFunc:  func(_ event.DeleteEvent) bool { return true },\n\t\tGenericFunc: func(_ event.GenericEvent) bool { return false },\n\t}\n}\n\n// Reconcile reconciles a ConfigMap.\nfunc (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {\n\tlog := logf.FromContext(ctx)\n\n\tsecret := &corev1.Secret{}\n\tif err := r.Client.Get(ctx, req.NamespacedName, secret); err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\tlog.V(1).Info(\"Object is gone, stop reconciling\")\n\t\t\treturn reconcile.Result{}, nil\n\t\t}\n\t\treturn reconcile.Result{}, fmt.Errorf(\"error retrieving object from store: %w\", err)\n\t}\n\n\t// Perform a typical operation in this example controller.\n\t// Create a ConfigMap with a controller reference to the watched Secret.\n\tlog.V(1).Info(\"Reconciling object\")\n\n\tconfigMap := &corev1.ConfigMap{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      \"checksums-\" + secret.Name,\n\t\t\tNamespace: secret.Namespace,\n\t\t\tLabels:    maps.Clone(secret.Labels),\n\t\t},\n\t\tData: make(map[string]string, len(secret.Data)),\n\t}\n\tconfigMap.Labels[\"secret\"] = secret.Name\n\n\t// Calculate the checksum for every Secret key and populate it in the ConfigMap.\n\tfor key, data := range secret.Data {\n\t\tchecksum := sha256.Sum256(data)\n\t\tconfigMap.Data[key] = hex.EncodeToString(checksum[:])\n\t}\n\n\tif err := controllerutil.SetControllerReference(secret, configMap, r.Client.Scheme()); err != nil {\n\t\treturn reconcile.Result{}, err\n\t}\n\n\treturn reconcile.Result{}, client.IgnoreAlreadyExists(r.Client.Create(ctx, configMap))\n}\n"
  },
  {
    "path": "cmd/sharder/app/app.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage app\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/go-logr/logr\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n\t\"k8s.io/component-base/version\"\n\t\"k8s.io/component-base/version/verflag\"\n\t\"k8s.io/klog/v2\"\n\t\"sigs.k8s.io/controller-runtime/pkg/healthz\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/controller\"\n\tshardingmetrics \"github.com/timebertt/kubernetes-controller-sharding/pkg/metrics\"\n\thealthzutils \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/healthz\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/webhook\"\n)\n\n// Name is a const for the name of this component.\nconst Name = \"sharder\"\n\n// NewCommand creates a new cobra.Command for running sharder.\nfunc NewCommand() *cobra.Command {\n\topts := newOptions()\n\n\tcmd := &cobra.Command{\n\t\tUse:   Name,\n\t\tShort: \"Launch the \" + Name,\n\t\tArgs:  cobra.NoArgs,\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\tverflag.PrintAndExitIfRequested()\n\n\t\t\tif err := opts.complete(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tlog := zap.New(zap.UseFlagOptions(opts.zapOptions))\n\t\t\tlogf.SetLogger(log)\n\t\t\tklog.SetLogger(log)\n\n\t\t\tlog.Info(\"Starting \"+Name, \"version\", version.Get())\n\t\t\tcmd.Flags().VisitAll(func(flag *pflag.Flag) {\n\t\t\t\tlog.Info(fmt.Sprintf(\"FLAG: --%s=%s\", flag.Name, flag.Value))\n\t\t\t})\n\n\t\t\t// don't output usage on further errors raised during execution\n\t\t\tcmd.SilenceUsage = true\n\t\t\t// further errors will be logged properly, don't duplicate\n\t\t\tcmd.SilenceErrors = true\n\n\t\t\treturn run(cmd.Context(), log, opts)\n\t\t},\n\t}\n\n\tflags := cmd.Flags()\n\tverflag.AddFlags(flags)\n\topts.addFlags(flags)\n\n\treturn cmd\n}\n\nfunc run(ctx context.Context, log logr.Logger, opts *options) error {\n\tlog.Info(\"Setting up manager\")\n\tmgr, err := manager.New(opts.restConfig, opts.managerOptions)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlog.Info(\"Setting up health check endpoints\")\n\tif err := mgr.AddHealthzCheck(\"ping\", healthz.Ping); err != nil {\n\t\treturn err\n\t}\n\tif err := mgr.AddReadyzCheck(\"cache-sync\", healthzutils.CacheSync(mgr.GetCache())); err != nil {\n\t\treturn err\n\t}\n\n\tlog.Info(\"Adding controllers to manager\")\n\tif err := controller.AddToManager(ctx, mgr, opts.config); err != nil {\n\t\treturn fmt.Errorf(\"failed adding controllers to manager: %w\", err)\n\t}\n\n\tlog.Info(\"Adding webhooks to manager\")\n\tif err := webhook.AddToManager(ctx, mgr, opts.config); err != nil {\n\t\treturn fmt.Errorf(\"failed adding webhooks to manager: %w\", err)\n\t}\n\n\tlog.Info(\"Adding metrics to manager\")\n\tif err = shardingmetrics.AddToManager(mgr); err != nil {\n\t\treturn fmt.Errorf(\"failed adding metrics to manager: %w\", err)\n\t}\n\n\tlog.Info(\"Starting manager\")\n\treturn mgr.Start(ctx)\n}\n"
  },
  {
    "path": "cmd/sharder/app/options.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage app\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\tgoruntime \"runtime\"\n\t\"strconv\"\n\n\t\"github.com/spf13/pflag\"\n\t\"go.uber.org/zap/zapcore\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/runtime/serializer\"\n\t\"k8s.io/apimachinery/pkg/selection\"\n\tutilruntime \"k8s.io/apimachinery/pkg/util/runtime\"\n\t\"k8s.io/client-go/rest\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/cache\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client/config\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/metrics/filters\"\n\tmetricsserver \"sigs.k8s.io/controller-runtime/pkg/metrics/server\"\n\t\"sigs.k8s.io/controller-runtime/pkg/webhook\"\n\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\tutilclient \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/client\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/routes\"\n)\n\nvar scheme = utilclient.SharderScheme\n\ntype options struct {\n\tconfigFile string\n\tzapOptions *zap.Options\n\n\tconfig         *configv1alpha1.SharderConfig\n\trestConfig     *rest.Config\n\tmanagerOptions manager.Options\n}\n\nfunc newOptions() *options {\n\treturn &options{\n\t\tzapOptions: &zap.Options{\n\t\t\tTimeEncoder: zapcore.ISO8601TimeEncoder,\n\t\t},\n\t}\n}\n\nfunc (o *options) addFlags(fs *pflag.FlagSet) {\n\tfs.StringVar(&o.configFile, \"config\", o.configFile, \"Path to configuration file.\")\n\n\tzapFlagSet := flag.NewFlagSet(\"zap\", flag.ContinueOnError)\n\to.zapOptions.BindFlags(zapFlagSet)\n\tfs.AddGoFlagSet(zapFlagSet)\n}\n\nfunc (o *options) complete() error {\n\to.config = &configv1alpha1.SharderConfig{}\n\n\t// load config file if specified\n\tif o.configFile != \"\" {\n\t\tdata, err := os.ReadFile(o.configFile)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error reading config file: %w\", err)\n\t\t}\n\n\t\tif err = runtime.DecodeInto(serializer.NewCodecFactory(scheme).UniversalDecoder(), data, o.config); err != nil {\n\t\t\treturn fmt.Errorf(\"error decoding config: %w\", err)\n\t\t}\n\t} else {\n\t\tscheme.Default(o.config)\n\t}\n\n\t// load rest config\n\tvar err error\n\to.restConfig, err = config.GetConfig()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error loading kubeconfig: %w\", err)\n\t}\n\to.applyConfigToRESTConfig()\n\n\t// bring everything together\n\to.managerOptions = manager.Options{\n\t\tScheme: scheme,\n\t\t// allows us to quickly handover leadership on restarts\n\t\tLeaderElectionReleaseOnCancel: true,\n\t}\n\to.applyConfigToManagerOptions()\n\to.applyCacheOptions()\n\n\tif err := o.applyOptionsOverrides(); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (o *options) applyConfigToRESTConfig() {\n\tif clientConnection := o.config.ClientConnection; clientConnection != nil {\n\t\tif clientConnection.QPS > 0 {\n\t\t\to.restConfig.QPS = clientConnection.QPS\n\t\t}\n\t\tif clientConnection.Burst > 0 {\n\t\t\to.restConfig.Burst = int(clientConnection.Burst)\n\t\t}\n\t}\n}\n\nfunc (o *options) applyConfigToManagerOptions() {\n\tif leaderElection := o.config.LeaderElection; leaderElection != nil {\n\t\to.managerOptions.LeaderElection = *leaderElection.LeaderElect\n\t\to.managerOptions.LeaderElectionResourceLock = leaderElection.ResourceLock\n\t\to.managerOptions.LeaderElectionID = leaderElection.ResourceName\n\t\to.managerOptions.LeaderElectionNamespace = leaderElection.ResourceNamespace\n\t\to.managerOptions.LeaseDuration = ptr.To(leaderElection.LeaseDuration.Duration)\n\t\to.managerOptions.RenewDeadline = ptr.To(leaderElection.RenewDeadline.Duration)\n\t\to.managerOptions.RetryPeriod = ptr.To(leaderElection.RetryPeriod.Duration)\n\t}\n\n\to.managerOptions.HealthProbeBindAddress = o.config.Health.BindAddress\n\n\tif o.config.Metrics.BindAddress != \"0\" {\n\t\tvar extraHandlers map[string]http.Handler\n\t\tif *o.config.Debugging.EnableProfiling {\n\t\t\textraHandlers = routes.ProfilingHandlers\n\t\t\tif *o.config.Debugging.EnableContentionProfiling {\n\t\t\t\tgoruntime.SetBlockProfileRate(1)\n\t\t\t}\n\t\t}\n\n\t\to.managerOptions.Metrics = metricsserver.Options{\n\t\t\tSecureServing:  true,\n\t\t\tBindAddress:    o.config.Metrics.BindAddress,\n\t\t\tFilterProvider: filters.WithAuthenticationAndAuthorization,\n\t\t\tExtraHandlers:  extraHandlers,\n\t\t}\n\t}\n\n\twebhookOptions := webhook.Options{}\n\tif serverConfig := o.config.Webhook.Server; serverConfig != nil {\n\t\twebhookOptions.CertDir = ptr.Deref(serverConfig.CertDir, \"\")\n\t\twebhookOptions.CertName = ptr.Deref(serverConfig.CertName, \"\")\n\t\twebhookOptions.KeyName = ptr.Deref(serverConfig.KeyName, \"\")\n\t}\n\to.managerOptions.WebhookServer = webhook.NewServer(webhookOptions)\n\n\to.managerOptions.GracefulShutdownTimeout = ptr.To(o.config.GracefulShutdownTimeout.Duration)\n}\n\nfunc (o *options) applyCacheOptions() {\n\t// filter lease cache for shard leases to avoid watching all leases in cluster\n\tleaseSelector := labels.NewSelector()\n\t{\n\t\tringRequirement, err := labels.NewRequirement(shardingv1alpha1.LabelControllerRing, selection.Exists, nil)\n\t\tutilruntime.Must(err)\n\t\tleaseSelector.Add(*ringRequirement)\n\t}\n\n\to.managerOptions.Cache = cache.Options{\n\t\tDefaultTransform: dropUnwantedMetadata,\n\n\t\tByObject: map[client.Object]cache.ByObject{\n\t\t\t&coordinationv1.Lease{}: {\n\t\t\t\tLabel: leaseSelector,\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (o *options) applyOptionsOverrides() error {\n\tvar err error\n\n\t// allow overriding leader election via env var for debugging purposes\n\tif leaderElectEnv, ok := os.LookupEnv(\"LEADER_ELECT\"); ok {\n\t\to.managerOptions.LeaderElection, err = strconv.ParseBool(leaderElectEnv)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error parsing LEADER_ELECT env var: %w\", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc dropUnwantedMetadata(i interface{}) (interface{}, error) {\n\tobj, ok := i.(client.Object)\n\tif !ok {\n\t\treturn i, nil\n\t}\n\n\tobj.SetManagedFields(nil)\n\tannotations := obj.GetAnnotations()\n\tdelete(annotations, \"kubectl.kubernetes.io/last-applied-configuration\")\n\tobj.SetAnnotations(annotations)\n\n\treturn obj, nil\n}\n"
  },
  {
    "path": "cmd/sharder/main.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"sigs.k8s.io/controller-runtime/pkg/manager/signals\"\n\n\t\"github.com/timebertt/kubernetes-controller-sharding/cmd/sharder/app\"\n)\n\nfunc main() {\n\tif err := app.NewCommand().ExecuteContext(signals.SetupSignalHandler()); err != nil {\n\t\tfmt.Println(err)\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "config/README.md",
    "content": "# config\n\nThis directory hosts manifests for deploying the sharding components.\nManifests of components for the development setup should be hosted in [`hack/config`](../hack/config) instead.\nI.e., this directory should only contain manifests that are useful for others wanting to reuse the sharding components in their setup.\n"
  },
  {
    "path": "config/certificate/certificate.yaml",
    "content": "apiVersion: cert-manager.io/v1\nkind: Certificate\nmetadata:\n  name: webhook-server\nspec:\n  issuerRef:\n    name: selfsigned\n  commonName: sharding:sharder:webhook\n  dnsNames:\n  - sharder.sharding-system\n  - sharder.sharding-system.svc\n  - sharder.sharding-system.svc.cluster.local\n  secretName: webhook-server\n"
  },
  {
    "path": "config/certificate/issuer.yaml",
    "content": "apiVersion: cert-manager.io/v1\nkind: Issuer\nmetadata:\n  name: selfsigned\nspec:\n  selfSigned: {}\n"
  },
  {
    "path": "config/certificate/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1alpha1\nkind: Component\n\nnamespace: sharding-system\n\nlabels:\n- includeSelectors: true\n  pairs:\n    app.kubernetes.io/name: controller-sharding\n\nresources:\n- certificate.yaml\n- issuer.yaml\n\npatches:\n- patch: |\n    apiVersion: apps/v1\n    kind: Deployment\n    metadata:\n      name: sharder\n      namespace: sharding-system\n    spec:\n      template:\n        spec:\n          containers:\n          - name: sharder\n            volumeMounts:\n            - name: cert\n              mountPath: /tmp/k8s-webhook-server/serving-certs\n          volumes:\n          - name: cert\n            secret:\n              secretName: webhook-server\n"
  },
  {
    "path": "config/crds/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nlabels:\n- includeSelectors: true\n  pairs:\n    app.kubernetes.io/name: controller-sharding\n\nresources:\n- namespace.yaml\n- sharding.timebertt.dev_controllerrings.yaml\n"
  },
  {
    "path": "config/crds/namespace.yaml",
    "content": "apiVersion: v1\nkind: Namespace\nmetadata:\n  name: sharding-system\n"
  },
  {
    "path": "config/crds/sharding.timebertt.dev_controllerrings.yaml",
    "content": "---\napiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.19.0\n  name: controllerrings.sharding.timebertt.dev\nspec:\n  group: sharding.timebertt.dev\n  names:\n    kind: ControllerRing\n    listKind: ControllerRingList\n    plural: controllerrings\n    singular: controllerring\n  scope: Cluster\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .status.conditions[?(@.type == \"Ready\")].status\n      name: Ready\n      type: string\n    - jsonPath: .status.availableShards\n      name: Available\n      type: string\n    - jsonPath: .status.shards\n      name: Shards\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1alpha1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          ControllerRing declares a virtual ring of sharded controller instances. Objects of the specified resources are\n          distributed across shards of this ring. Objects in all namespaces are considered unless a namespaceSelector is\n          specified.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec contains the specification of the desired behavior of\n              the ControllerRing.\n            properties:\n              namespaceSelector:\n                description: |-\n                  NamespaceSelector overwrites the webhook configs' namespaceSelector.\n                  If set, this selector should exclude the kube-system and sharding-system namespaces.\n                  If omitted, the default namespaceSelector from the SharderConfig is used.\n                  Note: changing/unsetting this selector will not remove labels from objects in namespaces that were previously\n                  included.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements.\n                      The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies\n                            to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              resources:\n                description: Resources specifies the list of resources that are distributed\n                  across shards in this ControllerRing.\n                items:\n                  description: RingResource specifies a resource along with controlled\n                    resources that is distributed across shards in a ring.\n                  properties:\n                    controlledResources:\n                      description: |-\n                        ControlledResources are additional resources that are distributed across shards in the ControllerRing.\n                        These resources are controlled by the controller's main resource, i.e., they have an owner reference with\n                        controller=true back to the GroupResource of this RingResource.\n                        Typically, the controller also watches objects of this resource and enqueues the owning object (of the main\n                        resource) whenever the status of a controlled object changes.\n                      items:\n                        description: |-\n                          GroupResource specifies a Group and a Resource, but does not force a version.  This is useful for identifying\n                          concepts during lookup stages without having partially valid types\n                        properties:\n                          group:\n                            type: string\n                          resource:\n                            type: string\n                        required:\n                        - group\n                        - resource\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - group\n                      - resource\n                      x-kubernetes-list-type: map\n                    group:\n                      type: string\n                    resource:\n                      type: string\n                  required:\n                  - group\n                  - resource\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - group\n                - resource\n                x-kubernetes-list-type: map\n            type: object\n          status:\n            description: Status contains the most recently observed status of the\n              ControllerRing.\n            properties:\n              availableShards:\n                description: AvailableShards is the total number of available shards\n                  of this ring.\n                format: int32\n                type: integer\n              conditions:\n                description: |-\n                  Conditions represents the observations of a foo's current state.\n                  Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\"\n                items:\n                  description: Condition contains details for one aspect of the current\n                    state of this API Resource.\n                  properties:\n                    lastTransitionTime:\n                      description: |-\n                        lastTransitionTime is the last time the condition transitioned from one status to another.\n                        This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.\n                      format: date-time\n                      type: string\n                    message:\n                      description: |-\n                        message is a human readable message indicating details about the transition.\n                        This may be an empty string.\n                      maxLength: 32768\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        observedGeneration represents the .metadata.generation that the condition was set based upon.\n                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\n                        with respect to the current state of the instance.\n                      format: int64\n                      minimum: 0\n                      type: integer\n                    reason:\n                      description: |-\n                        reason contains a programmatic identifier indicating the reason for the condition's last transition.\n                        Producers of specific condition types may define expected values and meanings for this field,\n                        and whether the values are considered a guaranteed API.\n                        The value should be a CamelCase string.\n                        This field may not be empty.\n                      maxLength: 1024\n                      minLength: 1\n                      pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$\n                      type: string\n                    status:\n                      description: status of the condition, one of True, False, Unknown.\n                      enum:\n                      - \"True\"\n                      - \"False\"\n                      - Unknown\n                      type: string\n                    type:\n                      description: type of condition in CamelCase or in foo.example.com/CamelCase.\n                      maxLength: 316\n                      pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - message\n                  - reason\n                  - status\n                  - type\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              observedGeneration:\n                description: The generation observed by the ControllerRing controller.\n                format: int64\n                type: integer\n              shards:\n                description: Shards is the total number of shards of this ring.\n                format: int32\n                type: integer\n            required:\n            - availableShards\n            - shards\n            type: object\n        type: object\n        x-kubernetes-validations:\n        - message: ControllerRing name must not be longer than 63 characters\n          rule: size(self.metadata.name) <= 63\n    served: true\n    storage: true\n    subresources:\n      status: {}\n"
  },
  {
    "path": "config/default/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../crds\n- ../sharder\n\ncomponents:\n- ../certificate\n"
  },
  {
    "path": "config/monitoring/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nnamespace: sharding-system\n\nresources:\n- servicemonitor.yaml\n# provide prometheus running in namespace \"monitoring\" with the permissions required for service discovery in namespace\n# \"sharding-system\"\n- prometheus_rbac.yaml\n"
  },
  {
    "path": "config/monitoring/prometheus_rbac.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n  name: prometheus-k8s-service-discovery\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - services\n  - endpoints\n  - pods\n  verbs:\n  - get\n  - list\n  - watch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n  name: prometheus-k8s-service-discovery\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: prometheus-k8s-service-discovery\nsubjects:\n- kind: ServiceAccount\n  name: prometheus-k8s\n  namespace: monitoring\n"
  },
  {
    "path": "config/monitoring/servicemonitor.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  name: sharder\n  labels:\n    app.kubernetes.io/name: controller-sharding\n    app.kubernetes.io/component: sharder\nspec:\n  jobLabel: app.kubernetes.io/component\n  endpoints:\n  - path: /metrics\n    port: metrics\n    scheme: https\n    bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    honorLabels: true\n    interval: 10s\n    scrapeTimeout: 10s\n    tlsConfig:\n      insecureSkipVerify: true\n    relabelings:\n    - action: labelmap\n      regex: \"__meta_kubernetes_pod_label_label_prometheus_io_(.*)\"\n      replacement: \"${1}\"\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: controller-sharding\n      app.kubernetes.io/component: sharder\n"
  },
  {
    "path": "config/rbac/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- serviceaccount.yaml\n- leader_election.yaml\n- metrics_auth.yaml\n- role.yaml\n- rolebinding.yaml\n- pprof_reader.yaml\n\npatches:\n# This is a workaround for controller-gen not being able to handle colons in the role name option.\n- target:\n    kind: ClusterRole\n    name: sharder\n  patch: |\n    - op: replace\n      path: /metadata/name\n      value: sharding:sharder\n"
  },
  {
    "path": "config/rbac/leader_election.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  name: sharding:sharder:leader-election\nrules:\n- apiGroups:\n  - coordination.k8s.io\n  resources:\n  - leases\n  verbs:\n  - get\n  - create\n  - update\n- apiGroups:\n  - \"\"\n  resources:\n  - events\n  verbs:\n  - create\n  - patch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: sharding:sharder:leader-election\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: sharding:sharder:leader-election\nsubjects:\n- kind: ServiceAccount\n  name: sharder\n  namespace: sharding-system\n"
  },
  {
    "path": "config/rbac/metrics_auth.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: sharding:metrics-auth\nrules:\n- apiGroups:\n  - authentication.k8s.io\n  resources:\n  - tokenreviews\n  verbs:\n  - create\n- apiGroups:\n  - authorization.k8s.io\n  resources:\n  - subjectaccessreviews\n  verbs:\n  - create\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: sharding:metrics-auth\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: sharding:metrics-auth\nsubjects:\n- kind: ServiceAccount\n  name: sharder\n  namespace: sharding-system\n"
  },
  {
    "path": "config/rbac/pprof_reader.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: sharding:sharder:pprof-reader\nrules:\n- nonResourceURLs:\n  - \"/debug/pprof/allocs\"\n  - \"/debug/pprof/block\"\n  - \"/debug/pprof/goroutine\"\n  - \"/debug/pprof/heap\"\n  - \"/debug/pprof/mutex\"\n  - \"/debug/pprof/profile\"\n  - \"/debug/pprof/symbol\"\n  - \"/debug/pprof/threadcreate\"\n  - \"/debug/pprof/trace\"\n  verbs:\n  - get\n"
  },
  {
    "path": "config/rbac/role.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: sharder\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - events\n  verbs:\n  - create\n  - patch\n- apiGroups:\n  - \"\"\n  resources:\n  - namespaces\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - admissionregistration.k8s.io\n  resources:\n  - mutatingwebhookconfigurations\n  verbs:\n  - create\n  - patch\n- apiGroups:\n  - coordination.k8s.io\n  resources:\n  - leases\n  verbs:\n  - delete\n  - get\n  - list\n  - patch\n  - update\n  - watch\n- apiGroups:\n  - sharding.timebertt.dev\n  resources:\n  - controllerrings\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - sharding.timebertt.dev\n  resources:\n  - controllerrings/status\n  verbs:\n  - patch\n  - update\n"
  },
  {
    "path": "config/rbac/rolebinding.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: sharding:sharder\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: sharding:sharder\nsubjects:\n- kind: ServiceAccount\n  name: sharder\n  namespace: sharding-system\n"
  },
  {
    "path": "config/rbac/serviceaccount.yaml",
    "content": "apiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: sharder\nautomountServiceAccountToken: false\n"
  },
  {
    "path": "config/sharder/config.yaml",
    "content": "apiVersion: config.sharding.timebertt.dev/v1alpha1\nkind: SharderConfig\nwebhook:\n  config:\n    annotations:\n      # Technically, this belongs to the certificate component. It doesn't hurt to add this by default though.\n      # Kustomize doesn't allow merging config files in ConfigMaps. Hence, keep the full default config here.\n      cert-manager.io/inject-ca-from: sharding-system/webhook-server\n"
  },
  {
    "path": "config/sharder/deployment.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: sharder\n  namespace: sharding-system\n  labels:\n    app.kubernetes.io/component: sharder\nspec:\n  replicas: 2\n  selector:\n     matchLabels:\n       app.kubernetes.io/component: sharder\n  template:\n    metadata:\n      labels:\n        app.kubernetes.io/component: sharder\n    spec:\n      automountServiceAccountToken: true\n      securityContext:\n        runAsNonRoot: true\n      containers:\n      - name: sharder\n        image: sharder:latest\n        args:\n        - --config=/config.yaml\n        volumeMounts:\n        - name: config\n          mountPath: /config.yaml\n          subPath: config\n        env:\n        - name: DISABLE_HTTP2\n          value: \"true\"\n        ports:\n        - name: webhook\n          containerPort: 9443\n          protocol: TCP\n        - name: metrics\n          containerPort: 8080\n          protocol: TCP\n        securityContext:\n          allowPrivilegeEscalation: false\n        livenessProbe:\n          httpGet:\n            path: /healthz\n            port: 8081\n          initialDelaySeconds: 15\n          periodSeconds: 20\n        readinessProbe:\n          httpGet:\n            path: /readyz\n            port: 8081\n          initialDelaySeconds: 5\n          periodSeconds: 10\n        resources:\n          limits:\n            cpu: 200m\n            memory: 512Mi\n          requests:\n            cpu: 100m\n            memory: 256Mi\n      volumes:\n      - name: config\n        configMap:\n          name: sharder-config\n      serviceAccountName: sharder\n      terminationGracePeriodSeconds: 30\n      topologySpreadConstraints:\n      - maxSkew: 1\n        topologyKey: kubernetes.io/hostname\n        whenUnsatisfiable: ScheduleAnyway\n        labelSelector:\n          matchLabels:\n            app.kubernetes.io/component: sharder\n      - maxSkew: 1\n        topologyKey: topology.kubernetes.io/zone\n        whenUnsatisfiable: ScheduleAnyway\n        labelSelector:\n          matchLabels:\n            app.kubernetes.io/component: sharder\n"
  },
  {
    "path": "config/sharder/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nnamespace: sharding-system\n\ngeneratorOptions:\n  disableNameSuffixHash: true\n\nlabels:\n- includeSelectors: true\n  pairs:\n    app.kubernetes.io/name: controller-sharding\n\nimages:\n- name: sharder\n  newName: ghcr.io/timebertt/kubernetes-controller-sharding/sharder\n  newTag: latest\n\nresources:\n- deployment.yaml\n- poddisruptionbudget.yaml\n- service.yaml\n- ../rbac\n\nconfigMapGenerator:\n- name: sharder-config\n  options:\n    labels:\n      app.kubernetes.io/component: sharder\n  files:\n  - config=../sharder/config.yaml\n"
  },
  {
    "path": "config/sharder/poddisruptionbudget.yaml",
    "content": "apiVersion: policy/v1\nkind: PodDisruptionBudget\nmetadata:\n  labels:\n    app.kubernetes.io/component: sharder\n  name: sharder\nspec:\n  maxUnavailable: 1\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: sharder\n"
  },
  {
    "path": "config/sharder/service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: sharder\n  namespace: sharding-system\n  labels:\n    app.kubernetes.io/component: sharder\nspec:\n  type: ClusterIP\n  selector:\n    app.kubernetes.io/component: sharder\n  ports:\n  - port: 443\n    name: webhook\n    protocol: TCP\n    targetPort: webhook\n  - port: 8080\n    name: metrics\n    protocol: TCP\n    targetPort: metrics\n"
  },
  {
    "path": "docs/README.md",
    "content": "# Documentation Index\n\n- [Getting Started With Controller Sharding](getting-started.md) ⬅️ start here, if you're new to the project\n- [Install the Sharding Components](installation.md)\n- [Implement Sharding in Your Controller](implement-sharding.md)\n- [Monitoring the Sharding Components](monitoring.md)\n- [Design](design.md)\n- [Evaluating the Sharding Mechanism](evaluation.md)\n- [Development and Testing Setup](development.md)\n"
  },
  {
    "path": "docs/design.md",
    "content": "# Design\n\nThis document explains the sharding design in more detail.\nPlease also consider reading the respective design chapters in the [study project](https://github.com/timebertt/thesis-controller-sharding) and [Master's thesis](https://github.com/timebertt/masters-thesis-controller-sharding) as long as this document is not detailed enough.\n\n## Architecture\n\nThis section outlines the key components and mechanism involved in achieving controller sharding.\n\n![Sharding Architecture](assets/architecture.svg)\n\n### The Sharder Component\n\nThe sharder is a central component deployed once per cluster.\nIt serves as the overall orchestrator of the sharding mechanism.\nIt facilitates membership and failure detection, partitioning, object assignment, and preventing concurrency.\nThe component is designed to be generic, i.e., it can be used for implementing sharding for any kind of controller (independent of the used programming language and controller framework).\n\n### Shard Leases\n\nMultiple instances of the actual controller are deployed.\nNotably, no leader election is performed, and there is no designated single active instance.\nInstead, each controller instance maintains an individual shard `Lease` labeled with the ring's name, allowing them to announce themselves to the sharder for membership and failure detection.\nThe sharder watches these leases to build a hash ring with the available instances.\n\n### The `ControllerRing` Resource and Sharder Webhook\n\nRings of controllers are configured through the use of the `ControllerRing` custom resource.\nThe sharder creates a `MutatingWebhookConfiguration` for each `ControllerRing` to perform assignments for objects associated with the ring.\nThe sharder webhook is called on `CREATE` and `UPDATE` requests for configured resources, but only for objects that don't have the ring-specific shard label, i.e., for unassigned objects.\n\nThe sharder uses the consistent hashing ring to determine the desired shard and adds the shard label during admission accordingly.\nShards then use a label selector for the shard label with their own instance name to restrict the cache and controller to the subset of objects assigned to them.\n\nFor the controller's \"main\" object (configured in `ControllerRing.spec.resources[]`), the object's API group, `kind`, `namespace`, and `name` are concatenated to form its hash key.\nFor objects controlled by other objects (configured in `ControllerRing.spec.resources[].controlledResources[]`), the sharder utilizes information about the controlling object (`ownerReference` with `controller=true`) to calculate the object's hash key.\nThis ensures that owned objects are consistently assigned to the same shard as their owner.\n\n### Object Movements and Rebalancing\n\nThe sharder also runs a controller that facilitates object movements when necessary.\nFor this, it watches the shard leases and ensures all object assignments are up-to-date whenever the set of available instances changes.\nIt also performs periodic syncs to cater for objects that failed to be assigned during admission.\n\nWhen a shard voluntarily releases its lease (i.e., on graceful shutdown), the sharder recognizes that the shard was removed from the ring and sets its state to `dead`.\nWith this, the shard is no longer considered for object assignments.\nThe orphaned `Lease` is cleaned up after 1 minute.\nThe sharder immediately moves objects that were assigned to the removed shard to the remaining available shards.\nFor this, the controller simply removes the shard label on all affected objects and lets the webhook reassign them.\nAs the original shard is not available anymore, moving the objects doesn't need to be coordinated and the sharder can immediately move objects.\n\nWhen a shard fails to renew its lease in time, the sharder acquires the lease for ensuring API server reachability/functionality.\nIf this is successful, the shard is considered `dead` which leads to forcefully reassigning the objects.\n\nWhen a new shard is added to the ring, the sharder recognizes the available shard lease and performs rebalancing accordingly.\nIn contrast to moving objects from unavailable shards, this needs to be coordinated to prevent multiple shards from acting on the same object concurrently.\nOtherwise, the shards might perform conflicting actions which might lead to a broken state of the objects.\n\nDuring rebalancing, the sharder drains objects from the old shard by adding the drain label.\nThis operation is acknowledged by the old shard by removing both the shard and the drain label\nThis in turn triggers the sharder webhook again, which assigns the object to the new shard.\n\n## Important Design Decisions\n\n### Don't Watch Sharded Objects\n\nDistributing a controller's reconciliations and cache across multiple instances works very well using the label selector approach.\nI.e., if you run 3 shards you can expect each shard to consume about a third of the CPU and memory consumption that a single instance responsible for all objects would.\nThe key to making Kubernetes controllers horizontally scalable however, is to ensure that the overhead of the sharding mechanism doesn't grow with the number of objects or rate of reconciliations.\nOtherwise, we would only shift the scalability limitation to another component without removing it.\nIn other words, sharding Kubernetes controller obviously comes with an overhead – just as sharding a database.\nHowever, this overhead needs to be constant or at maximum grow in a sublinear fashion.\n\nIn this project's [first iteration](https://github.com/timebertt/thesis-controller-sharding), the sharder didn't use a webhook to assign objects during admission.\nInstead, the sharder ran a controller with watches for the sharded objects.\nAlthough the sharder used lightweight metadata-only watches, the overhead still grew with the number of sharded objects.\nIn the study project's evaluation (see chapter 6 of the paper), it was shown that the setup was already capable of distributing resource consumption across multiple instances but still faced a scalability limitation in the sharder's resource consumption.\n\nIn the [second iteration](https://github.com/timebertt/masters-thesis-controller-sharding), the sharder doesn't watch the sharded objects anymore.\nThe watch events were only needed for labeling unassigned objects immediately.\nThis is facilitated by the sharder webhook instead now.\nThe other cases were object assignments need to be performed (membership changes) are unrelated to the objects themselves.\nHence, the controller only needs to watch a small number of objects related to the number of shards.\nWith this, the overhead of the sharding mechanism is independent of the number of objects.\nIn fact, it is negligible as show in [Evaluating the Sharding Mechanism](evaluation.md).\nThe comparisons show that the sharder's resource consumption is almost constant apart from spikes during periodic syncs.\n\n### Minimize Impact on the Critical Path\n\nWhile the use of mutating webhooks might allow dropping watches for the sharded objects, they can have a significant impact on API requests, e.g., regarding request latency.\nTo minimize the impact of the sharder's webhook on the overall request latency, the webhook is configured to only react on precisely the set of objects configured in the `ControllerRing` and only for `CREATE` and `UPDATE` requests of unassigned objects.\nWith this the webhook is only on the critical path during initial object creation and whenever the set of available shards requires reassignments.\n\nFurthermore, webhooks can cause API requests to fail entirely.\nTo reduce the risk of such failures, the sharder is deployed in a highly available fashion and the webhook is configured with a low timeout and failure policy `Ignore`.\nWith this, API requests still succeed if the webhook server is shortly unreachable.\nIn such cases, the object will be unassigned until the next sync of the sharder controller.\nI.e., the design prioritizes availability of the API over consistency of assignments.\n\nAlso, the sharding mechanism doesn't touch the critical path of actual reconciliations.\n\n### Minimize Impact on the Control Plane\n\nBy using label selectors on the watch connections of individual shards, the load on the API server is not changed compared to a single controller instance that watches all objects without a selector.\nAdditionally, the sharder minimizes the extra load on the API server and etcd when it comes to `LIST` requests of all sharded objects (e.g., during periodic syncs).\nFor this, it only lists the metadata of the sharded objects (spec and status are irrelevant).\nAlso, it passes the [request parameter](https://kubernetes.io/docs/reference/using-api/api-concepts/#the-resourceversion-parameter) `resourceVersion=0` to the API server, which causes it to serve the request from the in-memory watch cache instead of performing a quorum read on etcd.\nIn other words, the design accepts slightly outdated data and with this slightly inconsistent object assignments in favor of better performance and scalability.\n\n## Limitations\n\n### Limited Support for `generateName`\n\nIn the first iteration (without the sharder webhook), the object's `uid` was the essential part of the hash key.\nWith the evolution of the mechanism to assign objects during admission using a mutating webhook, the object's `uid` cannot be used any longer as it is unset during admission for `CREATE` requests.\nHence, the sharder uses the object's `GroupVersionKind`, `namespace`, and `name` for calculating the hash key instead.\nThis works well and also supports calculating the same hash key for controlled objects by using information from `ownerReferences`.\n\nHowever, this also means that `generateName` is not supported for resources that are not controlled by other resources in the ring.\nThe reason is that `generateName` is not set during admission for `CREATE` requests similar to the `uid` field.\nNote, that `generateName` is still supported for objects that are controlled by other objects, as the controlled object's own name is not included in the hash key.\n\nThis tradeoff seems acceptable, as there are not many good use cases for `generateName`.\nIn general, using `generateName` in controllers makes it difficult to prevent incorrect actions (e.g., creating too many controlled objects) as the controller needs to track its own actions that used `generateName`.\nInstead, using deterministic naming based on the owning object (e.g., spec contents or `uid`) simplifies achieving correctness significantly.\nAll other use cases of using `generateName` for simply generating a random name of an object one doesn't really care about (e.g., in integration or load tests) can also generate a random suffix on the client side before submitting the request to the API server.\n\nHowever, if the API server set an object's `uid` or `generateName` before admission for `CREATE` requests, this limitation could be lifted.\n"
  },
  {
    "path": "docs/development.md",
    "content": "# Development and Testing Setup\n\nThis document explains more details of the development and testing setup that is also presented in [Getting Started With Controller Sharding](getting-started.md).\n\n## Development Cluster\n\nThe setup's basis is a local [kind](https://kind.sigs.k8s.io/) cluster.\nThis simplifies developing and testing the project as it comes without additional cost, can be thrown away easily, and one doesn't need to push development images to a remote registry.\nIn other words, there are no prerequisites for getting started with this project other than a [Go](https://go.dev/) and [Docker](https://www.docker.com/) installation.\n\n```bash\n# create a local cluster\nmake kind-up\n# target the kind cluster\nexport KUBECONFIG=$PWD/hack/kind_kubeconfig.yaml\n\n# delete the local cluster\nmake kind-down\n```\n\nIf you want to use another cluster for development (e.g., a remote cluster) simply set the `KUBECONFIG` environment variable as usual and all make commands will target the cluster pointed to by your kubeconfig.\nNote that you might need to push images to a remote registry though.\n\n## Components\n\nThe development setup reuses the deployment manifests of the main sharding components developed in this repository, located in [`config`](../config).\nSee [Install the Sharding Components](installation.md).\n\nIt also includes the [checksum-controller](../cmd/checksum-controller) as an example sharded controller (see [Implement Sharding in Your Controller](implement-sharding.md)) and the [webhosting-operator](../webhosting-operator/README.md) (see [Evaluating the Sharding Mechanism](evaluation.md)).\n\nApart from this, the development setup also includes some external components, located in [`hack/config`](../hack/config).\nThis includes [cert-manager](https://cert-manager.io/), [ingress-nginx](https://kubernetes.github.io/ingress-nginx/), [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus), [kyverno](https://kyverno.io/), and [parca](https://parca.dev/).\nThese components are installed for a seamless development and testing experience but also for this project's [Evaluation](evaluation.md) on a remote cluster in the cloud.\n\n## Deploying, Building, Running Using Skaffold\n\nUse `make deploy` to deploy all components with pre-built images using [skaffold](https://skaffold.dev/).\nYou can overwrite the used images via make variables, e.g., the `TAG` variable:\n\n```bash\nmake deploy TAG=latest\n```\n\nFor development, skaffold can build fresh images based on your local changes using [ko](https://ko.build/), load them into your local cluster, and deploy the configuration:\n\n```bash\nmake up\n```\n\nAlternatively, you can also start a skaffold-based dev loop which can automatically rebuild and redeploy images as soon as source files change:\n\n```bash\nmake dev\n# runs initial build and deploy...\n# press any key to trigger a fresh build after changing sources\n```\n\nIf you're not working with a local kind cluster, you need to set `SKAFFOLD_DEFAULT_REPO` to a registry that you can push the dev images to:\n\n```bash\nmake up SKAFFOLD_DEFAULT_REPO=ghcr.io/timebertt/dev-images\n```\n\nRemove all components from the cluster:\n\n```bash\nmake down\n```\n\nFor any skaffold-based make command, you can set `SKAFFOLD_MODULE` to target only a specific part of the [skaffold configuration](../hack/config/skaffold.yaml):\n\n```bash\nmake dev SKAFFOLD_MODULE=sharder\n```\n\n## Running on the Host Machine\n\nInstead of running the sharder in the cluster, you can also run it on your host machine targeting your local kind cluster.\nThis doesn't deploy all components as before but only cert-manager for injecting the webhook's CA bundle.\nAssuming a fresh kind cluster:\n\n```bash\nmake run\n```\n\nNow, create the `ControllerRing` and run a local `checksum-controller`:\n\n```bash\nmake run-checksum-controller\n```\n\nYou should see that the shard successfully announced itself to the sharder:\n\n```bash\n$ kubectl get lease -L alpha.sharding.timebertt.dev/controllerring,alpha.sharding.timebertt.dev/state\nNAME                           HOLDER                         AGE   CONTROLLERRING        STATE\nchecksum-controller-lhrlt6h4   checksum-controller-lhrlt6h4   6s    checksum-controller   ready\n\n$ kubectl get controllerring\nNAME                  READY   AVAILABLE   SHARDS   AGE\nchecksum-controller   True    1           1        13s\n```\n\nRunning the `checksum-controller` locally gives you the option to test non-graceful termination, i.e., a scenario where the shard fails to renew its lease in time.\nSimply press `Ctrl-C` twice:\n\n```bash\nmake run-checksum-controller\n...\n^C2023-11-24T15:16:50.948+0100\tINFO\tShutting down gracefully in 2 seconds, send another SIGINT or SIGTERM to shutdown non-gracefully\n^Cexit status 1\n```\n\n## Testing the Sharding Setup\n\nIndependent of the used setup (skaffold-based or running on the host machine), you should be able to create sharded `Secrets` in the `default` namespace as configured in the `example` `ControllerRing`.\nThe `ConfigMaps` created by the `checksum-controller` should be assigned to the same shard as the owning `Secret`:\n\n```bash\n$ kubectl create secret generic foo --from-literal foo=bar\nsecret/foo created\n\n$ kubectl get cm,secret -L shard.alpha.sharding.timebertt.dev/checksum-controller\nNAME                      DATA   AGE   CHECKSUM-CONTROLLER\nconfigmap/checksums-foo   1      1s    checksum-controller-lhrlt6h4\n\nNAME         TYPE     DATA   AGE   CHECKSUM-CONTROLLER\nsecret/foo   Opaque   1      1s    checksum-controller-lhrlt6h4\n```\n\n## Monitoring\n\nWhen using the skaffold-based setup, you also get a full monitoring setup for observing and analyzing the components' resource usage.\n\nTo access the monitoring dashboards and metrics in Grafana, simply forward its port and open http://localhost:3000/ in your browser:\n\n```bash\nkubectl -n monitoring port-forward svc/grafana 3000 &\n```\n\nThe password for Grafana's `admin` user is written to `hack/config/monitoring/default/grafana_admin_password.secret.txt`.\n\nBe sure to check out the controller-runtime dashboard: http://localhost:3000/d/PuCBL3zVz/controller-runtime-controllers\n\n## Continuous Profiling\n\nTo dig deeper into the components' resource usage, you can deploy the continuous profiling setup based on [Parca](https://parca.dev/):\n\n```bash\nmake up SKAFFOLD_MODULE=profiling SKAFFOLD_PROFILE=profiling\n```\n\nTo access the profiling data in Parca, simply forward its port and open http://localhost:7070/ in your browser:\n\n```bash\nkubectl -n parca port-forward svc/parca 7070 &\n```\n\nFor accessing Parca through its `Ingress`, use the basic auth password for the `parca` user from `hack/config/profiling/parca_password.secret.txt`.\n\nNote that the Parca deployment doesn't implement retention for profiling data.\nI.e., the Parca data volume will grow infinitely as long as Parca is running.\nTo shut down Parca after analyzing the collected profiles and destroying the persistent volume use the following command:\n\n```bash\nmake down SKAFFOLD_MODULE=profiling SKAFFOLD_PROFILE=profiling\n```\n"
  },
  {
    "path": "docs/evaluation.md",
    "content": "# Evaluating the Sharding Mechanism\n\nThis guide describes how the sharding mechanism implemented in this repository is evaluated and outlines the key results of the evaluation performed in the associated [Master's thesis](https://github.com/timebertt/masters-thesis-controller-sharding).\nPlease refer to the thesis' evaluation section for more details.\n\n## Components\n\nThe evaluation setup builds upon the [Development and Testing Setup](development.md) but adds a few more components.\nTo demonstrate and evaluate the implemented sharding mechanisms using a fully functioning controller, a dedicated example operator was developed: the [webhosting-operator](../webhosting-operator/README.md).\nWhile the webhosting-operator is developed in the same repository, it only serves as an example.\n\nWhen deploying the sharding components using `make deploy` or `make up`, the webhosting-operator is automatically deployed along with the other evaluation components.\nAssuming you're in the repository's root directory, you can deploy the webhosting-operator using:\n\n```bash\n# deploy the webhosting-operator using pre-built images\nmake deploy SKAFFOLD_MODULE=webhosting-operator TAG=latest\n# alternatively, build and deploy fresh images\nmake up SKAFFOLD_MODULE=webhosting-operator\n```\n\nTo perform a quick test of the webhosting-operator, create some example `Website` objects:\n\n```bash\n$ kubectl apply -k webhosting-operator/config/samples\n...\n\n$ kubectl -n project-foo get website,deploy,ing,svc,cm -L shard.alpha.sharding.timebertt.dev/webhosting-operator\nNAME                                       THEME      PHASE   SINCE   AGE   WEBHOSTING-OPERATOR\nwebsite.webhosting.timebertt.dev/kubecon   exciting   Ready   1s      3s    webhosting-operator-5f7854768d-8n59m\nwebsite.webhosting.timebertt.dev/library   lame       Ready   1s      3s    webhosting-operator-5f7854768d-j67tj\n\nNAME                             READY   UP-TO-DATE   AVAILABLE   AGE   WEBHOSTING-OPERATOR\ndeployment.apps/kubecon-b5ed55   1/1     1            1           3s    webhosting-operator-5f7854768d-8n59m\ndeployment.apps/library-185298   1/1     1            1           3s    webhosting-operator-5f7854768d-j67tj\n\nNAME                                       CLASS   HOSTS                      ADDRESS   PORTS     AGE   WEBHOSTING-OPERATOR\ningress.networking.k8s.io/kubecon-b5ed55   nginx   webhosting.timebertt.dev             80, 443   3s    webhosting-operator-5f7854768d-8n59m\ningress.networking.k8s.io/library-185298   nginx   webhosting.timebertt.dev             80, 443   3s    webhosting-operator-5f7854768d-j67tj\n\nNAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE   WEBHOSTING-OPERATOR\nservice/kubecon-b5ed55   ClusterIP   100.82.167.176   <none>        8080/TCP   3s    webhosting-operator-5f7854768d-8n59m\nservice/library-185298   ClusterIP   100.82.224.52    <none>        8080/TCP   3s    webhosting-operator-5f7854768d-j67tj\n\nNAME                       DATA   AGE   WEBHOSTING-OPERATOR\nconfigmap/kubecon-b5ed55   2      3s    webhosting-operator-5f7854768d-8n59m\nconfigmap/library-185298   2      3s    webhosting-operator-5f7854768d-j67tj\n```\n\nYou can now visit the created websites at http://localhost:8088/project-foo/homepage and http://localhost:8088/project-foo/official.\nYou can also visit your [local webhosting dashboard](http://127.0.0.1:3000/d/NbmNpqEnk/webhosting?orgId=1) after forwarding the Grafana port:\n\n```bash\nkubectl -n monitoring port-forward svc/grafana 3000\n```\n\nThis dashboard uses metrics exported by [webhosting-operator](../webhosting-operator/pkg/metrics) about its API objects, i.e., `kube_website_*` and `kube_theme_*`.\nThere is also a dashboard about the [sharding of websites](http://127.0.0.1:3000/d/7liIybkVk/sharding?orgId=1).\n\nIn addition to creating the preconfigured websites, you can also generate some more random websites using the [samples-generator](../webhosting-operator/cmd/samples-generator):\n\n```bash\n# create a random number of websites per project namespace (up to 50 each)\n$ go run ./webhosting-operator/cmd/samples-generator\ncreated 32 Websites in project \"project-foo\"\n```\n\n## Load Tests\n\nThe [experiment](./cmd/experiment) tool allows executing different scenarios for load testing the webhosting-operator, which are used for evaluating the sharding mechanism:\n\n```text\n$ go run ./webhosting-operator/cmd/experiment -h\nUsage:\n  experiment [command]\n\nAvailable Scenarios\n  basic          Basic load test, create 9k websites in 15 minutes\n  chaos          Create 4.5k websites over 15 minutes and terminate a random shard every 5 minutes\n  rolling-update Create 9k websites in 15 minutes while rolling the operator\n  scale-out      Measure scale-out properties with a high churn rate\n...\n```\n\nA load test scenario can be executed using one of these commands:\n\n```bash\n# run the basic scenario from your development machine (not recommended)\ngo run ./cmd/experiment basic\n\n# build the experiment image and run the basic scenario as a Job on the cluster\nmake up SKAFFOLD_MODULE=experiment EXPERIMENT_SCENARIO=basic\n\n# use a pre-built experiment image to run the basic scenario as a Job on the cluster\nmake deploy SKAFFOLD_MODULE=experiment EXPERIMENT_SCENARIO=basic TAG=latest\n```\n\nAll scenarios put load on webhosting-operator by creating and mutating a large amount of `Website` objects.\nHowever, creating soo many `Websites` would waste immense compute power just to run thousands of dummy websites.\nHence, webhosting-operator creates `Deployments` of `Websites` in load tests with `spec.replicas=0`.\nIt also doesn't expose `Websites` created in load tests via `Ingress` objects by setting `spec.ingressClassName=fake`.\nOtherwise, this would overload the ingress controller, which is not what the experiment is actually supposed to load test.\n\nWhen running load test experiments on the cluster, a `ServiceMonitor` is created to instruct prometheus to scrape `experiment`.\nAs the tool is based on controller-runtime as well, the controller-runtime metrics can be used for visualizing the load test scenario and verifying that the tool is able to generate the desired load.\n\n## Experiment Setup\n\nAs a local kind cluster cannot handle such high load, a remote cluster is used to perform the load test experiments.\nFor this, a [Gardener](https://github.com/gardener/gardener) installation on [STACKIT](https://www.stackit.de/en/) is used to create a cluster based on the [sample manifest](../hack/config/shoot.yaml).\n[external-dns](https://github.com/kubernetes-sigs/external-dns) is used for publicly exposing the monitoring and continuous profiling endpoints, as well as `Websites` created outside of load test experiments.\n\n```bash\n# gardenctl target --garden ...\nkubectl apply -f hack/config/shoot.yaml\n\n# gardenctl target --shoot ...\nkubectl apply --server-side -k hack/config/external-dns\nkubectl -n external-dns create secret generic google-clouddns-timebertt-dev --from-literal project=$PROJECT_NAME --from-file service-account.json=$SERVICE_ACCOUNT_FILE\n\n# gardenctl target --control-plane\nkubectl apply --server-side -k hack/config/policy/controlplane\n```\n\nIn addition to the described components, [kyverno](https://github.com/kyverno/kyverno) is deployed to the cluster itself (shoot cluster) and to the control plane (seed cluster).\nIn the cluster itself, kyverno policies are used for scheduling the sharder and webhosting-operator to the dedicated `sharding` worker pool and experiment to the dedicated `experiment` worker pool.\nThis makes sure that these components run on machines isolated from other system components and don't content for compute resources during load tests.\n\nFurthermore, kyverno policies are added to the control plane to ensure a static size of etcd, kube-apiserver, and kube-controller-manager (requests=limits for guaranteed resources, disable vertical autoscaling, 4 replicas of kube-apiserver and disable horizontal autoscaling).\nAlso, kube-controller-manager's client-side rate limiting is disabled (ref https://github.com/timebertt/kubernetes-controller-sharding/pull/610, [SIG api-machinery recommendation](https://kubernetes.slack.com/archives/C0EG7JC6T/p1680889646346859?thread_ts=1680791299.631439&cid=C0EG7JC6T)) and HTTP/2 is disabled so that API requests are distributed across API server instances (ref https://github.com/gardener/gardener/issues/8810).\nThis is done to make load test experiments more stable and their results more reproducible.\n\n## Measurements\n\nAfter executing a load test experiment, the [measure](../webhosting-operator/cmd/measure) tool is used for retrieving the key metrics from Prometheus.\nIt takes a configurable set of measurements in the form of Prometheus queries and stores them in CSV-formatted files for further analysis (with numpy/pandas) and visualization (with matplotlib).\nPlease see the [results directory](https://github.com/timebertt/masters-thesis-controller-sharding/tree/main/results) in the Master's thesis' repository for the exact measurements taken.\n\nThe scale of the controller setup is measured in two dimensions:\n\n1. The number of API objects that the controller watches and reconciles.\n2. The churn rate of API objects, i.e., the rate of object creations, updates, and deletions.\n\n```yaml\nqueries:\n- name: website-count # dimension 1\n  query: |\n    sum(kube_website_info)\n- name: website-churn # dimension 2\n  query: |\n    sum(rate(\n      controller_runtime_reconcile_total{\n        job=\"experiment\", result!=\"error\",\n        controller=~\"website-(generator|deleter|mutator)\"\n      }[1m]\n    )) by (controller)\n```\n\n## SLIs / SLOs\n\nTo consider a controller setup as performing adequately, the following SLOs\nneed to be satisfied:\n\n1. The time of enqueuing object keys for reconciliation for every controller, measured as the 99th percentile per cluster-day, is at maximum 1 second.\n2. The latency of realizing the desired state of objects for every controller, excluding reconciliation time of controlled objects, until observed by a watch request, measured as the 99th percentile per cluster-day, is at maximum x, where x depends on the controller.\n\nIn case of the `Website` controller, 5 is chosen for x.\n\n```yaml\nqueries:\n- name: latency-queue # SLO 1\n  type: instant\n  slo: 1\n  query: |\n    histogram_quantile(0.99, sum by (le) (rate(\n      workqueue_queue_duration_seconds_bucket{\n        job=\"webhosting-operator\", name=\"website\"\n      }[$__range]\n    )))\n- name: latency-reconciliation # SLO 2\n  type: instant\n  slo: 5\n  query: |\n    histogram_quantile(0.99, sum by (le) (rate(\n      experiment_website_reconciliation_duration_seconds_bucket{\n        job=\"experiment\"\n      }[$__range]\n    )))\n```\n\n## Comparison\n\nThe following graphs show the generated load and compare the resulting CPU, memory, and network usage of the components in three different setups when running the `basic` experiment scenario (~9k websites created over 15m):\n\n- external sharder: 3 webhosting-operator pods (shards) + 2 sharder pods (the new approach implemented in this repository, second iteration for the Master's thesis)\n- internal sharder: 3 webhosting-operator pods (3 shards, 1 acts as the sharder) (the old approach, first iteration for the study project)\n- singleton: 1 webhosting-operator pod (traditional leader election setup without sharding)\n\n![Generated load in basic scenario](assets/comparison-load.svg)\n\n![CPU comparison in basic scenario](assets/comparison-cpu.svg)\n\n![Memory comparison in basic scenario](assets/comparison-memory.svg)\n\n![Network comparison in basic scenario](assets/comparison-network.svg)\n\nThe new external sharding approach proves to scale best.\nThe individual shards consume about a third of the singleton controller's usage (close to optimum).\nAlso, the sharder pods consume a low static amount of resources. \nMost importantly, the sharder's resource usage is independent of the number of sharded objects.\n\n## Horizontal Scalability\n\nTo evaluate the horizontal scalability of the sharding mechanism (external sharder), the maximum load capacity is determined for different numbers of instances (1, 2, 3, 4, 5).\nWhile the load increases, cumulative SLIs from the start of the experiment are calculated.\nWhen the cumulative SLI grows above the SLO, the current count and churn rate are the maximum load capacity.\nAs shown in the last plot, the system's capacity increases almost linearly with the number of added instances.\n\n![Generated load in scale-out scenario](assets/scale-out-load.svg)\n\n![Cumulative controller SLIs in scale-out scenario](assets/scale-out-slis.svg)\n\n![Load capacity increase with added instances in scale-out scenario](assets/scale-out-capacity.svg)\n"
  },
  {
    "path": "docs/getting-started.md",
    "content": "# Getting Started With Controller Sharding\n\nThis guide walks you through getting started with controller sharding in a local cluster.\n\nIt sets up the sharder and an example sharded controller so that you can see the components in action.\nThis is great for trying out the project for the first time and learning about the basic concepts.\n\n## Setup\n\nCreate a local cluster using [kind](https://kind.sigs.k8s.io/) and deploy all components:\n\n```bash\nmake kind-up\nexport KUBECONFIG=$PWD/hack/kind_kubeconfig.yaml\nmake deploy TAG=latest\n```\n\nThe sharder is running in the `sharding-system` namespace and the example shard (checksum-controller) is deployed to the `default` namespace:\n\n```bash\n$ kubectl -n sharding-system get po\nNAME                      READY   STATUS    RESTARTS   AGE\nsharder-99fcf97b4-hpm6w   1/1     Running   0          17s\nsharder-99fcf97b4-zr7rj   1/1     Running   0          17s\n$ kubectl get po\nNAME                                  READY   STATUS    RESTARTS   AGE\nchecksum-controller-c95c4fdb6-7jb2v   1/1     Running   0          18s\nchecksum-controller-c95c4fdb6-hv8pb   1/1     Running   0          18s\nchecksum-controller-c95c4fdb6-rtvrm   1/1     Running   0          18s\n```\n\n## The `ControllerRing` and `Lease` Objects\n\nWe can see that the `ControllerRing` object is ready and reports 3 available shards out of 3 total shards:\n\n```bash\n$ kubectl get controllerring checksum-controller\nNAME                  READY   AVAILABLE   SHARDS   AGE\nchecksum-controller   True    3           3        25s\n```\n\nAll shards announce themselves to the sharder by maintaining an individual `Lease` object with the `alpha.sharding.timebertt.dev/controllerring` label.\nWe can observe that the sharder recognizes all shards as available by looking at the `alpha.sharding.timebertt.dev/state` label:\n\n```bash\n$ kubectl get lease -L alpha.sharding.timebertt.dev/controllerring,alpha.sharding.timebertt.dev/state\nNAME                                  HOLDER                                AGE   CONTROLLERRING        STATE\nchecksum-controller-c95c4fdb6-7jb2v   checksum-controller-c95c4fdb6-7jb2v   44s   checksum-controller   ready\nchecksum-controller-c95c4fdb6-hv8pb   checksum-controller-c95c4fdb6-hv8pb   44s   checksum-controller   ready\nchecksum-controller-c95c4fdb6-rtvrm   checksum-controller-c95c4fdb6-rtvrm   44s   checksum-controller   ready\n```\n\nThe `ControllerRing` object specifies which API resources should be sharded.\nOptionally, it allows selecting the namespaces in which API resources are sharded:\n\n```yaml\napiVersion: sharding.timebertt.dev/v1alpha1\nkind: ControllerRing\nmetadata:\n  name: checksum-controller\nspec:\n  resources:\n  - group: \"\"\n    resource: secrets\n    controlledResources:\n    - group: \"\"\n      resource: configmaps\n  namespaceSelector:\n    matchLabels:\n      kubernetes.io/metadata.name: default\n```\n\nIn our case, the `checksum-controller` reconciles `Secrets` in the `default` namespace and creates a `ConfigMap` including the secret data's checksums.\nThe created `ConfigMaps` are controlled by the respective `Secret`, i.e., there they have an `ownerReference` with `controller=true` to the `Secret`.\n\n## The Sharder Webhook\n\nThe sharder created a `MutatingWebhookConfiguration` for the resources listed in our `ControllerRing` specification:\n\n```bash\n$ kubectl get mutatingwebhookconfiguration -l alpha.sharding.timebertt.dev/controllerring=checksum-controller\nNAME                                 WEBHOOKS   AGE\ncontrollerring-checksum-controller   1          71s\n```\n\nLet's examine the webhook configuration for more details.\nWe can see that the webhook targets a ring-specific path served by the `sharder`.\nIt reacts on `CREATE` and `UPDATE` requests of the configured resources, where the object doesn't have the ring-specific shard label.\nI.e., it gets called for unassigned objects and adds the shard assignment label during admission.\n\n```yaml\napiVersion: admissionregistration.k8s.io/v1\nkind: MutatingWebhookConfiguration\nmetadata:\n  name: controllerring-checksum-controller\nwebhooks:\n- clientConfig:\n    service:\n      name: sharder\n      namespace: sharding-system\n      path: /webhooks/sharder/controllerring/checksum-controller\n      port: 443\n  name: sharder.sharding.timebertt.dev\n  namespaceSelector:\n    matchLabels:\n      kubernetes.io/metadata.name: default\n  objectSelector:\n    matchExpressions:\n    - key: shard.alpha.sharding.timebertt.dev/checksum-controller\n      operator: DoesNotExist\n  rules:\n  - apiGroups:\n    - \"\"\n    apiVersions:\n    - '*'\n    operations:\n    - CREATE\n    - UPDATE\n    resources:\n    - secrets\n    scope: '*'\n  - apiGroups:\n    - \"\"\n    apiVersions:\n    - '*'\n    operations:\n    - CREATE\n    - UPDATE\n    resources:\n    - configmaps\n    scope: '*'\n```\n\n## Creating Sharded Objects\n\nWe can observe the behavior of the webhook by creating a first example object.\nWhen we create a `Secret`, the webhook assigns it to one of the available controller instances by adding the ring-specific shard label.\nIt performs a consistent hashing algorithm, where it hashes both the object's key (consisting of API group, `kind`, `namespace`, and `name`) and the shards' names onto a virtual ring.\nIt picks the shard with the hash value that is next to the object's hash clock-wise.\n\n```bash\n$ kubectl create secret generic foo --from-literal foo=bar -oyaml\napiVersion: v1\ndata:\n  foo: YmFy\nkind: Secret\nmetadata:\n  labels:\n    shard.alpha.sharding.timebertt.dev/checksum-controller: checksum-controller-c95c4fdb6-hv8pb\n  name: foo\n  namespace: default\ntype: Opaque\n```\n\nWe can see that the responsible shard reconciled the `Secret` and created a `ConfigMap` for it.\nSimilar to the `Secret`, the `ConfigMap` was also assigned by the webhook.\nIn this case however, the sharder uses the information about the owning `Secret` for calculating the object's hash key.\nWith this, owned objects are always assigned to the same shard as their owner.\nThis is done because the controller typically needs to reconcile the owning object whenever the status of an owned object changes.\nE.g., the `Deployment` controller watches `ReplicaSets` and continues rolling updates of the owning `Deployment` as soon as the owned `ReplicaSet` has the number of wanted replicas.\n\n```bash\n$ kubectl get configmap checksums-foo -oyaml\napiVersion: v1\ndata:\n  foo: fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9\nkind: ConfigMap\nmetadata:\n  labels:\n    shard.alpha.sharding.timebertt.dev/checksum-controller: checksum-controller-c95c4fdb6-hv8pb\n  name: checksums-foo\n  namespace: default\n  ownerReferences:\n  - apiVersion: v1\n    controller: true\n    kind: Secret\n    name: foo\n```\n\nLet's create a few more `Secrets` and observe the distribution of objects across shards:\n\n```bash\n$ for i in $(seq 1 9); do k create secret generic foo$i ; done\n$ kubectl get secret,configmap -L shard.alpha.sharding.timebertt.dev/checksum-controller\nNAME          TYPE     DATA   AGE   CHECKSUM-CONTROLLER\nsecret/foo    Opaque   1      39s   checksum-controller-c95c4fdb6-hv8pb\nsecret/foo1   Opaque   0      10s   checksum-controller-c95c4fdb6-rtvrm\nsecret/foo2   Opaque   0      10s   checksum-controller-c95c4fdb6-7jb2v\nsecret/foo3   Opaque   0      10s   checksum-controller-c95c4fdb6-rtvrm\nsecret/foo4   Opaque   0      10s   checksum-controller-c95c4fdb6-hv8pb\nsecret/foo5   Opaque   0      10s   checksum-controller-c95c4fdb6-rtvrm\nsecret/foo6   Opaque   0      10s   checksum-controller-c95c4fdb6-hv8pb\nsecret/foo7   Opaque   0      10s   checksum-controller-c95c4fdb6-7jb2v\nsecret/foo8   Opaque   0      10s   checksum-controller-c95c4fdb6-rtvrm\nsecret/foo9   Opaque   0      10s   checksum-controller-c95c4fdb6-hv8pb\n\nNAME                         DATA   AGE     CHECKSUM-CONTROLLER\nconfigmap/checksums-foo      1      39s     checksum-controller-c95c4fdb6-hv8pb\nconfigmap/checksums-foo1     0      10s     checksum-controller-c95c4fdb6-rtvrm\nconfigmap/checksums-foo2     0      10s     checksum-controller-c95c4fdb6-7jb2v\nconfigmap/checksums-foo3     0      10s     checksum-controller-c95c4fdb6-rtvrm\nconfigmap/checksums-foo4     0      10s     checksum-controller-c95c4fdb6-hv8pb\nconfigmap/checksums-foo5     0      10s     checksum-controller-c95c4fdb6-rtvrm\nconfigmap/checksums-foo6     0      10s     checksum-controller-c95c4fdb6-hv8pb\nconfigmap/checksums-foo7     0      10s     checksum-controller-c95c4fdb6-7jb2v\nconfigmap/checksums-foo8     0      10s     checksum-controller-c95c4fdb6-rtvrm\nconfigmap/checksums-foo9     0      10s     checksum-controller-c95c4fdb6-hv8pb\n```\n\n## Removing Shards From the Ring\n\nLet's see what happens when the set of available shards changes.\nWe can observe the actions that the sharder takes using `kubectl get secret --show-labels -w --output-watch-events --watch-only` in a new terminal session.\n\nFirst, let's scale down the sharded controller to remove one shard from the ring:\n\n```bash\n$ kubectl scale deployment checksum-controller --replicas 2\ndeployment.apps/checksum-controller scaled\n```\n\nThe shard releases its `Lease` by setting the `holderIdentity` field to the empty string.\nThe sharder recognizes that the shard was removed from the ring and sets its state to `dead`.\nWith this, the shard is no longer considered for object assignments.\nThe orphaned `Lease` is cleaned up after 1 minute.\n\n```bash\n$ kubectl get lease -L alpha.sharding.timebertt.dev/state\nNAME                                  HOLDER                                AGE     STATE\nchecksum-controller-c95c4fdb6-7jb2v   checksum-controller-c95c4fdb6-7jb2v   3m34s   ready\nchecksum-controller-c95c4fdb6-hv8pb   checksum-controller-c95c4fdb6-hv8pb   3m34s   ready\nchecksum-controller-c95c4fdb6-rtvrm                                         3m34s   dead\n```\n\nWe can observe that the sharder immediately moved objects that were assigned to the removed shard to the remaining available shards.\nFor this, the sharder controller simply removes the shard label on all affected objects and lets the webhook reassign them.\nAs the original shard is not available anymore, moving the objects doesn't need to be coordinated and the sharder can immediately move objects.\n\n```bash\n$ kubectl get secret --show-labels -w --output-watch-events --watch-only\nEVENT      NAME   TYPE     DATA   AGE   LABELS\nMODIFIED   foo1   Opaque   0      48s   shard.alpha.sharding.timebertt.dev/checksum-controller=checksum-controller-c95c4fdb6-hv8pb\nMODIFIED   foo3   Opaque   0      48s   shard.alpha.sharding.timebertt.dev/checksum-controller=checksum-controller-c95c4fdb6-7jb2v\nMODIFIED   foo5   Opaque   0      48s   shard.alpha.sharding.timebertt.dev/checksum-controller=checksum-controller-c95c4fdb6-hv8pb\nMODIFIED   foo8   Opaque   0      48s   shard.alpha.sharding.timebertt.dev/checksum-controller=checksum-controller-c95c4fdb6-7jb2v\n```\n\n## Adding Shards to the Ring\n\nNow, let's scale up our sharded controller to add a new shard to the ring.\n\n```bash\n$ kubectl scale deployment checksum-controller --replicas 3\ndeployment.apps/checksum-controller scaled\n```\n\nWe can observe that the new `Lease` object is in state `ready`.\nWith this, the new shard is immediately considered for assignment of new objects.\n\n```bash\n$ kubectl get lease -L alpha.sharding.timebertt.dev/state\nNAME                                  HOLDER                                AGE     STATE\nchecksum-controller-c95c4fdb6-7jb2v   checksum-controller-c95c4fdb6-7jb2v   4m19s   ready\nchecksum-controller-c95c4fdb6-hv8pb   checksum-controller-c95c4fdb6-hv8pb   4m19s   ready\nchecksum-controller-c95c4fdb6-kdrss   checksum-controller-c95c4fdb6-kdrss   4s      ready\n```\n\nIn this case, a rebalancing needs to happen and the sharder needs to move objects away from available shards to the new shard.\nIn contrast to moving objects from unavailable shards, this needs to be coordinated to prevent multiple shards from acting on the same object concurrently.\nOtherwise, the shards might perform conflicting actions which might lead to a broken state of the objects.\n\nFor this, the sharder adds the drain label to all objects that should be moved to the new shard.\nThis asks the currently responsible shard to stop reconciling the object and acknowledge the movement.\nAs soon as the controller observes the drain label, it removes it again along with the shard label.\nThis triggers the sharder webhook which immediately assigns the object to the desired shard.\n\n```bash\n$ kubectl get secret --show-labels -w --output-watch-events --watch-only\nEVENT      NAME   TYPE     DATA   AGE    LABELS\nMODIFIED   foo5   Opaque   0      116s   drain.alpha.sharding.timebertt.dev/checksum-controller=true,shard.alpha.sharding.timebertt.dev/checksum-controller=checksum-controller-c95c4fdb6-hv8pb\nMODIFIED   foo8   Opaque   0      116s   drain.alpha.sharding.timebertt.dev/checksum-controller=true,shard.alpha.sharding.timebertt.dev/checksum-controller=checksum-controller-c95c4fdb6-7jb2v\nMODIFIED   foo5   Opaque   0      116s   shard.alpha.sharding.timebertt.dev/checksum-controller=checksum-controller-c95c4fdb6-kdrss\nMODIFIED   foo8   Opaque   0      116s   shard.alpha.sharding.timebertt.dev/checksum-controller=checksum-controller-c95c4fdb6-kdrss\n```\n\n## Clean Up\n\nSimply delete the local cluster to clean up:\n\n```bash\nmake kind-down\n```\n\n## Where To Go From Here?\n\nNow, you should have a basic understanding of how sharding for Kubernetes controllers works.\nIf you want to learn more about the individual components, the sharding architecture, and the reasoning behind it, see [Design](design.md).\nYou might also be interested in reading the [Evaluation](evaluation.md) document about load tests for sharded controllers and how this project helps in scaling Kubernetes controllers.\n\nIf you want to use sharding for your own controllers, see [Implement Sharding in Your Controller](implement-sharding.md).\n\nTo further experiment with the setup from this guide or to start developing changes to the sharding components, see [Development and Testing Setup](development.md).\n\nYou can also take a look at the remaining docs in the [documentation index](README.md).\n"
  },
  {
    "path": "docs/implement-sharding.md",
    "content": "# Implement Sharding in Your Controller\n\nThis guide walks you through implementing sharding for your own controller.\nPrerequisite for using a sharded controller setup is to install the sharding components in the cluster, see [Install the Sharding Components](installation.md).\n\n## Configuring the `ControllerRing`\n\nAfter installing the sharding components, you can go ahead and configure a `ControllerRing` object for your controller.\nFor all controllers that you want to shard, configure the controller's main resource and the controlled resources in `ControllerRing.spec.resources`.\n\nAs an example, let's consider a subset of kube-controller-manager's controllers: `Deployment` and `ReplicaSet`.\n\n- The `Deployment` controller reconciles the `deployments` resource and controls `replicasets`.\n- The `ReplicaSet` controller reconciles the `replicaset` resource and controls `pods`.\n\nThe corresponding `ControllerRing` for the `Deployment` controller would need to be configured like this:\n\n```yaml\napiVersion: sharding.timebertt.dev/v1alpha1\nkind: ControllerRing\nmetadata:\n  name: kube-controller-manager-deployment\nspec:\n  resources:\n  - group: apps\n    resource: deployments\n    controlledResources:\n    - group: apps\n      resource: replicasets\n```\n\nNote that the `ControllerRing` name must not be longer than 63 characters because it is used as part of the shard and drain label key (see below).\n\nTo allow the sharder to reassign the sharded objects during rebalancing, we need to grant the corresponding permissions.\nWe need to grant these permissions explicitly depending on what is configured in the `ControllerRing`.\nOtherwise, the sharder would basically require `cluster-admin` access.\nFor the above example, we would use these RBAC manifests:\n\n```yaml\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: sharding:controllerring:kube-controller-manager\nrules:\n- apiGroups:\n  - apps\n  resources:\n  - deployments\n  - replicaset\n  verbs:\n  - list\n  - patch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: sharding:controllerring:kube-controller-manager\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: sharding:controllerring:kube-controller-manager\nsubjects:\n- kind: ServiceAccount\n  name: sharder\n  namespace: sharding-system\n```\n\n## Implementation Changes\n\nTo support sharding in your Kubernetes controller, only three aspects need to be implemented:\n\n- announce ring membership and shard health: maintain individual shard `Leases` instead of performing leader election on a single `Lease`\n- only watch, cache, and reconcile objects assigned to the respective shard: add a shard-specific label selector to watches\n- acknowledge object movements during rebalancing: remove the drain and shard label when the drain label is set and stop reconciling the object\n\n[`pkg/shard`](../pkg/shard) contains reusable reference implementations for these aspects.\n[`cmd/checksum-controller`](../cmd/checksum-controller) serves as an example implementation for sharded controllers that shows how to put the pieces together in controllers based on [controller-runtime](https://github.com/kubernetes-sigs/controller-runtime).\nHowever, sharding can also be implemented in controllers that don't use controller-runtime or that are written in another programming language than Go.\n\nThe following sections outline the exact requirements that a sharded controller needs to fulfill and then show how to implement them in controllers based on controller-runtime.\nDon't be scared by the long descriptions.\nImplementing these aspects is simple (especially if reusing the helpers designed for controller-runtime controllers) and only needs to be done once.\nThe long descriptions just make sure the requirements are perfectly clear if you need to implement them yourself.\n\n### Shard Lease\n\nIn short: ensure your shard maintains a `Lease` object like this and only runs its controllers as long as it holds the `Lease`:\n\n```yaml\napiVersion: coordination.k8s.io/v1\nkind: Lease\nmetadata:\n  labels:\n    alpha.sharding.timebertt.dev/controllerring: my-controllerring\n  name: my-operator-565df55f4b-5vwpj\n  namespace: operator-system\nspec:\n  holderIdentity: my-operator-565df55f4b-5vwpj # needs to equal the Lease's name\n  leaseDurationSeconds: 15 # pick whatever you would use for leader election as well\n```\n\nMost controllers already perform leader election using a central `Lease` lock object.\nOnly if the instance is elected as the leader, it is allowed to run the controllers.\nIf it fails to renew the `Lease` in time, another instance is allowed to acquire the `Lease` and can run the controllers.\nHence, an instance must not run any controllers when it looses its `Lease`.\nIn fact, most implementations exit the entire process when failing to renew the lock for safety.\n\nOn graceful termination (e.g., during a rolling update), the active leader may release the lock by setting the `holderIdentity` field of the `Lease` to the empty string.\nThis allows another instance to acquire the `Lease` immediately without waiting for it to expire, which helps in quick leadership handovers.\n\nThe same mechanisms apply to sharded controllers.\nBut instead of using a central `Lease` object for all instances, each instance acquires and maintains its own `Lease` object to announce itself to the sharder.\nA shard may only run its controllers as long as it holds its shard `Lease`.\nI.e., when it fails to renew the shard `Lease` in time, it also needs to stop all controllers.\nSimilar to usual leader election, a shard may release its own shard `Lease` on graceful termination by removing the `holderIdentity`.\nThis immediately triggers reassignments by the sharder to minimize the duration where no shard is acting on a subset of objects.\n\nIn essence, all the existing machinery for leader election can be reused for maintaining the shard `Lease` – that is, with two minor changes.\nFirst, the shard `Lease` needs to be labelled with `alpha.sharding.timebertt.dev/controllerring=<controllerring-name>` to specify which `ControllerRing` the shard belongs to.\nSecond, the name of the shard `Lease` needs to match the `holderIdentity`.\nBy default, the instance's hostname is used for both values.\nIf the `holderIdentity` differs from the name, the sharder assumes that the shard is unavailable.\n\nIn controller-runtime, you can configure your shard to maintain its shard `Lease` as follows:\n\n```go\npackage main\n\nimport (\n\tshardlease \"github.com/timebertt/kubernetes-controller-sharding/pkg/shard/lease\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client/config\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n)\n\nfunc run() error {\n\trestConfig := config.GetConfigOrDie()\n\n\tshardLease, err := shardlease.NewResourceLock(restConfig, shardlease.Options{\n\t\tControllerRingName: \"my-controllerring\",\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmgr, err := manager.New(restConfig, manager.Options{\n\t\t// SHARD LEASE\n\t\t// Use manager's leader election mechanism for maintaining the shard lease.\n\t\t// With this, controllers will only run as long as manager holds the shard lease.\n\t\t// After graceful termination, the shard lease will be released.\n\t\tLeaderElection:                      true,\n\t\tLeaderElectionResourceLockInterface: shardLease,\n\t\tLeaderElectionReleaseOnCancel:       true,\n\n\t\t// other options ...\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// add controllers and start manager as usual ...\n\n\treturn nil\n}\n```\n\nNote that if you're using controller-runtime, the same manager instance cannot run sharded and non-sharded controllers as a manager can only run under a single resource lock (either leader election or shard lease).\n\n### Filtered Watch Cache\n\nIn short: use the following label selector on watches for all sharded resources listed in the `ControllerRing`.\n\n```text\nshard.alpha.sharding.timebertt.dev/my-controllerring: my-operator-565df55f4b-5vwpj\n```\n\nThe sharder assigns all sharded objects by adding a shard label that is specific to the `ControllerRing` (resources could be part of multiple `ControllerRings`).\nThe shard label's key consists of the `shard.alpha.sharding.timebertt.dev/` prefix followed by the `ControllerRing` name.\nAs the key part after the `/` must not exceed 63 characters, the `ControllerRing` name must not be longer than 63 characters.\nThe shard label's value is the name of the shard, i.e., the name of the shard lease and the shard lease's `holderIdentity`.\n\nOnce you have determined the shard label key for your `ControllerRing`, use it as a selector on all watches that your controller starts for any of the sharded resources.\nWith this, the shard will only cache the objects assigned to it and the controllers will only reconcile these objects.\n\nNote that when you use a label or field selector on a watch connection and the label or field changes so that the selector doesn't match anymore, the API server will emit a `DELETE` watch event.\n\nIn controller-runtime, you can configure your shard to only watch and reconcile assigned objects as follows.\nThis snippet works with controller-runtime v0.16 and v0.17, other versions might require deviating configuration.\n\n```go\npackage main\n\nimport (\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\t\"sigs.k8s.io/controller-runtime/pkg/cache\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n)\n\nfunc run() error {\n\t// ...\n\t\n\tmgr, err := manager.New(restConfig, manager.Options{\n\t\t// FILTERED WATCH CACHE\n\t\tCache: cache.Options{\n\t\t\t// Configure cache to only watch objects that are assigned to this shard.\n\t\t\t// This controller only watches sharded objects, so we can configure the label selector on the cache's global level.\n\t\t\t// If your controller watches sharded objects as well as non-sharded objects, use cache.Options.ByObject to configure\n\t\t\t// the label selector on object level.\n\t\t\tDefaultLabelSelector: labels.SelectorFromSet(labels.Set{\n\t\t\t\tshardingv1alpha1.LabelShard(\"my-controllerring\"): shardLease.Identity(),\n\t\t\t}),\n\t\t},\n\n\t\t// other options ...\n\t})\n\t\n\t// ...\n}\n```\n\n### Acknowledge Drain Operations\n\nIn short: ensure your sharded controller acknowledges drain operations.\nWhen the drain label like this is added by the sharder, the controller needs to remove both the shard and the drain label and stop reconciling the object.\n\n```text\ndrain.alpha.sharding.timebertt.dev/my-controllerring\n```\n\nWhen the sharder needs to move an object from an available shard to another shard for rebalancing, it first adds the drain label to instruct the currently responsible shard to stop reconciling the object.\nThe shard needs to acknowledge this operation, as the sharder must prevent concurrent reconciliations of the same object in multiple shards.\nThe drain label's key is specific to the `ControllerRing` and follows the same pattern as the shard label (see above).\nThe drain label's value is irrelevant, only the presence of the label is relevant.\n\nApart from changing the controller's business logic to first check the drain label, also ensure that the watch event filtering logic (predicates) always reacts on events with the drain label set independent of the controller's actual predicates.\n\nIn controller-runtime, you can reuse the helpers for constructing correct predicates and a wrapping reconciler that correctly implements the drain operation as follows:\n\n```go\npackage controller\n\nimport (\n\tshardcontroller \"github.com/timebertt/kubernetes-controller-sharding/pkg/shard/controller\"\n\t\"sigs.k8s.io/controller-runtime/pkg/builder\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n)\n\n// AddToManager adds a controller to the manager.\n// shardName must match the shard lease's name/identity.\nfunc (r *Reconciler) AddToManager(mgr manager.Manager, controllerRingName, shardName string) error {\n\t// ACKNOWLEDGE DRAIN OPERATIONS\n\t// Use the shardcontroller package as helpers for:\n\t// - a predicate that triggers when the drain label is present (even if the actual predicates don't trigger)\n\t// - wrapping the actual reconciler a reconciler that handles the drain operation for us\n\treturn builder.ControllerManagedBy(mgr).\n\t\tFor(&corev1.Secret{}, builder.WithPredicates(shardcontroller.Predicate(controllerRingName, shardName, MySecretPredicate()))).\n\t\tOwns(&corev1.ConfigMap{}, builder.WithPredicates(MyConfigMapPredicate())).\n\t\tComplete(\n\t\t\tshardcontroller.NewShardedReconciler(mgr).\n\t\t\t\tFor(&corev1.Secret{}). // must match the kind in For() above\n\t\t\t\tInControllerRing(controllerRingName).\n\t\t\t\tWithShardName(shardName).\n\t\t\t\tMustBuild(r),\n\t\t)\n}\n```\n"
  },
  {
    "path": "docs/installation.md",
    "content": "# Install the Sharding Components\n\nThis guide walks you through installing the sharding components from this repository in your cluster.\nThis procedure is independent of the controller that you want to use sharding for.\n\n## Main Components (required)\n\nFor now, only [kustomize](https://kustomize.io/) is supported as the deployment tool.\nAll deployment manifests for this repository's components are located in [`config`](../config) and can be used from there.\n\nThe `config/default` variant holds the default configuration for the sharding components.\nIt requires [cert-manager](https://cert-manager.io/) to be installed in the cluster for managing the webhook certificates.\nApply it using `kubectl`:\n\n```bash\nkubectl apply --server-side -k \"https://github.com/timebertt/kubernetes-controller-sharding//config/default?ref=main\"\n```\n\nYou can customize the configuration using the usual kustomize mechanisms:\n\n```bash\ncat >kustomization.yaml <<EOF\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- https://github.com/timebertt/kubernetes-controller-sharding//config/default?ref=main\n\nimages:\n- name: ghcr.io/timebertt/kubernetes-controller-sharding/sharder\n  newTag: latest\n\nreplicas:\n- name: sharder\n  count: 3\nEOF\n\nkubectl apply --server-side -k .\n```\n\nIf you can't apply the default configuration, e.g., because you don't want to use cert-manager for managing the webhook certificates, you can also apply the dedicated configurations individually.\nFirst apply the CRD and `sharding-system` namespace using the `config/crds` configuration, then apply the `sharder` itself using the `config/sharder` configuration.\nBe sure to mount your webhook server cert to `/tmp/k8s-webhook-server/serving-certs/tls.{crt,key}`.\n\n## Monitoring (optional)\n\n`config/monitoring` contains a `ServiceMonitor` for configuring metrics scraping for the sharder using the [prometheus-operator](https://prometheus-operator.dev/).\nSee [Monitoring the Sharding Components](monitoring.md) for more information on the exposed metrics.\n"
  },
  {
    "path": "docs/monitoring.md",
    "content": "# Monitoring the Sharding Components\n\nThis document explains the metrics exposed by the sharder for monitoring the sharding components.\n\nThe `sharder` service exposes metrics via `https` on the `8080` port at the `/metrics` endpoint.\nClients need to authenticate against the endpoint and must be authorized for `get` on the `nonResourceURL` `/metrics`.\nRefer to the example [`ServiceMonitor` manifest](../config/monitoring/servicemonitor.yaml) for more details.\nAlso see [Install the Sharding Components](installation.md#monitoring-optional).\n\nNote that all `sharder` instances export the same state metrics for high availability.\nAccordingly, you should use suitable aggregation functions for deduplicating time series, e.g.:\n\n```\nmax without (instance, pod) (controller_sharding_shard_state)\n```\n\n## Sharding Operations Metrics\n\n### `controller_sharding_assignments_total`\n\nType: counter  \nDescription: Total number of shard assignments by the sharder webhook per `ControllerRing` and GroupResource.\nThis counter is incremented every time the mutating webhook of the sharder assigns a sharded object (excluding dry-run requests).\n\n### `controller_sharding_movements_total`\n\nType: counter  \nDescription: Total number of shard movements triggered by the sharder controller per `ControllerRing` and GroupResource.\nThis counter is incremented every time the sharder controller triggers a direct object assignment, i.e., when an object needs to be moved away from an unavailable shard (or when an object has missed the webhook and needs to be assigned).\nThis only considers the sharder controller's side, i.e., the `controller_sharding_assignments_total` counter is incremented as well when the controller successfully triggers an assignment by the webhook.\n\n### `controller_sharding_drains_total`\n\nType: counter  \nDescription: Total number of shard drains triggered by the sharder controller per `ControllerRing` and GroupResource.\nThis counter is incremented every time the sharder controller triggers a drain operation, i.e., when an object needs to be moved away from an available shard.\nThis only considers the sharder controller's side, i.e., the `controller_sharding_assignments_total` counter is incremented as well when the shard removes the drain label as expect and thereby triggers an assignment by the webhook.\nThis doesn't consider the action taken by the shard.\n\n### `controller_sharding_ring_calculations_total`\n\nType: counter  \nDescription: Total number of hash ring calculations per `ControllerRing`.\nThis counter is incremented every time the sharder calculates a new consistent hash ring based on the shard leases.\n\n## `ControllerRing` State Metrics\n\n### `controller_sharding_controllerring_metadata_generation`\n\nType: gauge  \nDescription: The generation of a `ControllerRing`.\n\n### `controller_sharding_controllerring_observed_generation`\n\nType: gauge  \nDescription: The latest generation observed by the `ControllerRing` controller.\n\n### `controller_sharding_controllerring_status_shards`\n\nType: gauge  \nDescription: The ControllerRing's total number of shards observed by the `ControllerRing` controller.\n\n### `controller_sharding_controllerring_status_available_shards`\n\nType: gauge  \nDescription: The `ControllerRing`'s number of available shards observed by the `ControllerRing` controller.\n\n## Shard State Metrics\n\n### `controller_sharding_shard_info`\n\nType: gauge  \nDescription: Information about a shard.\n\n### `controller_sharding_shard_state`\n\nType: stateset  \nDescription: The shard's current state observed by the `shardlease` controller.\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/timebertt/kubernetes-controller-sharding\n\ngo 1.24.0\n\ntoolchain go1.25.7\n\nrequire (\n\tgithub.com/cespare/xxhash/v2 v2.3.0\n\tgithub.com/evanphx/json-patch v5.9.11+incompatible\n\tgithub.com/go-logr/logr v1.4.3\n\tgithub.com/google/uuid v1.6.0\n\tgithub.com/hashicorp/go-multierror v1.1.1\n\tgithub.com/onsi/ginkgo/v2 v2.28.1\n\tgithub.com/onsi/gomega v1.39.1\n\tgithub.com/prometheus/client_golang v1.23.2\n\tgithub.com/spf13/cobra v1.10.2\n\tgithub.com/spf13/pflag v1.0.10\n\tgo.uber.org/zap v1.27.1\n\tgomodules.xyz/jsonpatch/v2 v2.5.0\n\tk8s.io/api v0.34.4\n\tk8s.io/apimachinery v0.34.4\n\tk8s.io/client-go v0.34.4\n\tk8s.io/code-generator v0.34.4\n\tk8s.io/component-base v0.34.4\n\tk8s.io/klog/v2 v2.130.1\n\tk8s.io/utils v0.0.0-20260210185600-b8788abfbbc2\n\tsigs.k8s.io/controller-runtime v0.22.5\n)\n\nrequire (\n\tcel.dev/expr v0.24.0 // indirect\n\tgithub.com/Masterminds/semver/v3 v3.4.0 // indirect\n\tgithub.com/antlr4-go/antlr/v4 v4.13.0 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/blang/semver/v4 v4.0.0 // indirect\n\tgithub.com/cenkalti/backoff/v4 v4.3.0 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/emicklei/go-restful/v3 v3.12.2 // indirect\n\tgithub.com/evanphx/json-patch/v5 v5.9.11 // indirect\n\tgithub.com/felixge/httpsnoop v1.0.4 // indirect\n\tgithub.com/fsnotify/fsnotify v1.9.0 // indirect\n\tgithub.com/fxamacker/cbor/v2 v2.9.0 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/go-logr/zapr v1.3.0 // indirect\n\tgithub.com/go-openapi/jsonpointer v0.21.0 // indirect\n\tgithub.com/go-openapi/jsonreference v0.20.2 // indirect\n\tgithub.com/go-openapi/swag v0.23.0 // indirect\n\tgithub.com/go-task/slim-sprig/v3 v3.0.0 // indirect\n\tgithub.com/gogo/protobuf v1.3.2 // indirect\n\tgithub.com/google/btree v1.1.3 // indirect\n\tgithub.com/google/cel-go v0.26.0 // indirect\n\tgithub.com/google/gnostic-models v0.7.0 // indirect\n\tgithub.com/google/go-cmp v0.7.0 // indirect\n\tgithub.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect\n\tgithub.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect\n\tgithub.com/hashicorp/errwrap v1.1.0 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/josharian/intern v1.0.0 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/mailru/easyjson v0.7.7 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/pkg/errors v0.9.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/prometheus/client_model v0.6.2 // indirect\n\tgithub.com/prometheus/common v0.66.1 // indirect\n\tgithub.com/prometheus/procfs v0.16.1 // indirect\n\tgithub.com/stoewer/go-strcase v1.3.0 // indirect\n\tgithub.com/x448/float16 v0.8.4 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.1.0 // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect\n\tgo.opentelemetry.io/otel v1.35.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.35.0 // indirect\n\tgo.opentelemetry.io/otel/sdk v1.34.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.35.0 // indirect\n\tgo.opentelemetry.io/proto/otlp v1.5.0 // indirect\n\tgo.uber.org/multierr v1.11.0 // indirect\n\tgo.yaml.in/yaml/v2 v2.4.2 // indirect\n\tgo.yaml.in/yaml/v3 v3.0.4 // indirect\n\tgolang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect\n\tgolang.org/x/mod v0.32.0 // indirect\n\tgolang.org/x/net v0.49.0 // indirect\n\tgolang.org/x/oauth2 v0.30.0 // indirect\n\tgolang.org/x/sync v0.19.0 // indirect\n\tgolang.org/x/sys v0.40.0 // indirect\n\tgolang.org/x/term v0.39.0 // indirect\n\tgolang.org/x/text v0.33.0 // indirect\n\tgolang.org/x/time v0.9.0 // indirect\n\tgolang.org/x/tools v0.41.0 // indirect\n\tgolang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect\n\tgoogle.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect\n\tgoogle.golang.org/grpc v1.72.1 // indirect\n\tgoogle.golang.org/protobuf v1.36.8 // indirect\n\tgopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect\n\tgopkg.in/inf.v0 v0.9.1 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n\tk8s.io/apiextensions-apiserver v0.34.3 // indirect\n\tk8s.io/apiserver v0.34.3 // indirect\n\tk8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f // indirect\n\tk8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect\n\tsigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect\n\tsigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect\n\tsigs.k8s.io/randfill v1.0.0 // indirect\n\tsigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect\n\tsigs.k8s.io/yaml v1.6.0 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=\ncel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=\ngithub.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=\ngithub.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=\ngithub.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=\ngithub.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=\ngithub.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=\ngithub.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=\ngithub.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=\ngithub.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=\ngithub.com/evanphx/json-patch v5.9.11+incompatible h1:ixHHqfcGvxhWkniF1tWxBHA0yb4Z+d1UQi45df52xW8=\ngithub.com/evanphx/json-patch v5.9.11+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=\ngithub.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=\ngithub.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=\ngithub.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=\ngithub.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=\ngithub.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=\ngithub.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=\ngithub.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=\ngithub.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=\ngithub.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=\ngithub.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=\ngithub.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE=\ngithub.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=\ngithub.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=\ngithub.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=\ngithub.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=\ngithub.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=\ngithub.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=\ngithub.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=\ngithub.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=\ngithub.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=\ngithub.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=\ngithub.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=\ngithub.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=\ngithub.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=\ngithub.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=\ngithub.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=\ngithub.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=\ngithub.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=\ngithub.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI=\ngithub.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=\ngithub.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=\ngithub.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=\ngithub.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=\ngithub.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=\ngithub.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=\ngithub.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=\ngithub.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=\ngithub.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=\ngithub.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=\ngithub.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=\ngithub.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=\ngithub.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=\ngithub.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=\ngithub.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=\ngithub.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=\ngithub.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=\ngithub.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI=\ngithub.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE=\ngithub.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=\ngithub.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=\ngithub.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=\ngithub.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=\ngithub.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=\ngithub.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=\ngithub.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=\ngithub.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=\ngithub.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=\ngithub.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=\ngithub.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=\ngithub.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=\ngithub.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=\ngithub.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=\ngithub.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=\ngithub.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=\ngithub.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=\ngithub.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=\ngithub.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=\ngithub.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=\ngithub.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=\ngithub.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=\ngithub.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=\ngithub.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngo.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=\ngo.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=\ngo.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=\ngo.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=\ngo.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=\ngo.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=\ngo.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=\ngo.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=\ngo.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=\ngo.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=\ngo.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=\ngo.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=\ngo.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=\ngo.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=\ngo.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=\ngo.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=\ngo.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=\ngo.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=\ngo.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=\ngo.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=\ngo.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=\ngo.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=\ngo.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=\ngo.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=\ngolang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=\ngolang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=\ngolang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=\ngolang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=\ngolang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=\ngolang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=\ngolang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=\ngolang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=\ngolang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=\ngolang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=\ngolang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=\ngolang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=\ngolang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY=\ngolang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=\ngolang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=\ngolang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=\ngomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=\ngoogle.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA=\ngoogle.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=\ngoogle.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=\ngoogle.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=\ngopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=\ngopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=\ngopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nk8s.io/api v0.34.4 h1:Z5hsoQcZ2yBjelb9j5JKzCVo9qv9XLkVm5llnqS4h+0=\nk8s.io/api v0.34.4/go.mod h1:6SaGYuGPkMqqCgg8rPG/OQoCrhgSEV+wWn9v21fDP3o=\nk8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g=\nk8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0=\nk8s.io/apimachinery v0.34.4 h1:C5SiSzLEMyWIk53sSbnk0WlOOyqv/MFnWvuc/d6M+xc=\nk8s.io/apimachinery v0.34.4/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=\nk8s.io/apiserver v0.34.3 h1:uGH1qpDvSiYG4HVFqc6A3L4CKiX+aBWDrrsxHYK0Bdo=\nk8s.io/apiserver v0.34.3/go.mod h1:QPnnahMO5C2m3lm6fPW3+JmyQbvHZQ8uudAu/493P2w=\nk8s.io/client-go v0.34.4 h1:IXhvzFdm0e897kXtLbeyMpAGzontcShJ/gi/XCCsOLc=\nk8s.io/client-go v0.34.4/go.mod h1:tXIVJTQabT5QRGlFdxZQFxrIhcGUPpKL5DAc4gSWTE8=\nk8s.io/code-generator v0.34.4 h1:ri/HSQ1eCQ40pqTQ4HeEiC8UR/SaftH/syav9RL4b+c=\nk8s.io/code-generator v0.34.4/go.mod h1:JbvI8dtG5KB5HJSFzExSbvigBSG8gCncyMtdwg/NVbw=\nk8s.io/component-base v0.34.4 h1:jP4XqR48YelfXIlRpOHQgms5GebU23zSE6xcvTwpXDE=\nk8s.io/component-base v0.34.4/go.mod h1:uujRfLNOwNiFWz47eBjNZEj/Swn2cdhqI7lW2MeFdrU=\nk8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f h1:SLb+kxmzfA87x4E4brQzB33VBbT2+x7Zq9ROIHmGn9Q=\nk8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU=\nk8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=\nk8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=\nk8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=\nk8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=\nk8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=\nk8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=\nsigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM=\nsigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=\nsigs.k8s.io/controller-runtime v0.22.5 h1:v3nfSUMowX/2WMp27J9slwGFyAt7IV0YwBxAkrUr0GE=\nsigs.k8s.io/controller-runtime v0.22.5/go.mod h1:pc5SoYWnWI6I+cBHYYdZ7B6YHZVY5xNfll88JB+vniI=\nsigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=\nsigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=\nsigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=\nsigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=\nsigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=\nsigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=\nsigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=\nsigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=\n"
  },
  {
    "path": "go.work",
    "content": "go 1.24.0\n\ntoolchain go1.25.0\n\nuse (\n\t.\n\t./webhosting-operator\n)\n"
  },
  {
    "path": "go.work.sum",
    "content": "cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=\ncloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=\ncloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=\ngithub.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=\ngithub.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=\ngithub.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0 h1:f2Qw/Ehhimh5uO1fayV0QIW7DShEQqhtUfhYc+cBPlw=\ngithub.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0/go.mod h1:2bIszWvQRlJVmJLiuLhukLImRjKPcYdzzsx6darK02A=\ngithub.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=\ngithub.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=\ngithub.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY=\ngithub.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=\ngithub.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0=\ngithub.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs=\ngithub.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=\ngithub.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=\ngithub.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=\ngithub.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=\ngithub.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=\ngithub.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=\ngithub.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 h1:Om6kYQYDUk5wWbT0t0q6pvyM49i9XZAv9dDrkDA7gjk=\ngithub.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=\ngithub.com/coreos/go-oidc v2.3.0+incompatible h1:+5vEsrgprdLjjQ9FzIKAzQz1wwPD+83hQRfUIPh7rO0=\ngithub.com/coreos/go-oidc v2.3.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=\ngithub.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=\ngithub.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=\ngithub.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=\ngithub.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=\ngithub.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=\ngithub.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=\ngithub.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=\ngithub.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=\ngithub.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA=\ngithub.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A=\ngithub.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=\ngithub.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=\ngithub.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=\ngithub.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=\ngithub.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=\ngithub.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E=\ngithub.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=\ngithub.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc=\ngithub.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=\ngithub.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=\ngithub.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=\ngithub.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=\ngithub.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA=\ngithub.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU=\ngithub.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 h1:FbSCl+KggFl+Ocym490i/EyXF4lPgLoUtcSWquBM0Rs=\ngithub.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc=\ngithub.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=\ngithub.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=\ngithub.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b h1:ogbOPx86mIhFy764gGkqnkFC8m5PJA7sPzlk9ppLVQA=\ngithub.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=\ngithub.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4=\ngithub.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc=\ngithub.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=\ngithub.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=\ngithub.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=\ngithub.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=\ngithub.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=\ngithub.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=\ngithub.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=\ngithub.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=\ngithub.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=\ngithub.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=\ngithub.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=\ngithub.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=\ngithub.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=\ngithub.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=\ngithub.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A=\ngithub.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=\ngithub.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=\ngithub.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=\ngithub.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc=\ngithub.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=\ngithub.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=\ngithub.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=\ngithub.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=\ngithub.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=\ngithub.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=\ngithub.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=\ngithub.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=\ngithub.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=\ngithub.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE=\ngithub.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g=\ngithub.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE=\ngithub.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk=\ngithub.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=\ngithub.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=\ngithub.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 h1:S2dVYn90KE98chqDkyE9Z4N61UnQd+KOfgp5Iu53llk=\ngithub.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=\ngithub.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngithub.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM=\ngithub.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=\ngo.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I=\ngo.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM=\ngo.etcd.io/etcd/api/v3 v3.6.4 h1:7F6N7toCKcV72QmoUKa23yYLiiljMrT4xCeBL9BmXdo=\ngo.etcd.io/etcd/api/v3 v3.6.4/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk=\ngo.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0=\ngo.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI=\ngo.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A=\ngo.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo=\ngo.etcd.io/etcd/pkg/v3 v3.6.4 h1:fy8bmXIec1Q35/jRZ0KOes8vuFxbvdN0aAFqmEfJZWA=\ngo.etcd.io/etcd/pkg/v3 v3.6.4/go.mod h1:kKcYWP8gHuBRcteyv6MXWSN0+bVMnfgqiHueIZnKMtE=\ngo.etcd.io/etcd/server/v3 v3.6.4 h1:LsCA7CzjVt+8WGrdsnh6RhC0XqCsLkBly3ve5rTxMAU=\ngo.etcd.io/etcd/server/v3 v3.6.4/go.mod h1:aYCL/h43yiONOv0QIR82kH/2xZ7m+IWYjzRmyQfnCAg=\ngo.etcd.io/raft/v3 v3.6.0 h1:5NtvbDVYpnfZWcIHgGRk9DyzkBIXOi8j+DDp1IcnUWQ=\ngo.etcd.io/raft/v3 v3.6.0/go.mod h1:nLvLevg6+xrVtHUmVaTcTz603gQPHfh7kUAwV6YpfGo=\ngo.opentelemetry.io/contrib/detectors/gcp v1.34.0 h1:JRxssobiPg23otYU5SbWtQC//snGVIM3Tx6QRzlQBao=\ngo.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM=\ngolang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=\ngolang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=\ngolang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=\ngolang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=\ngolang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=\ngolang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=\ngolang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=\ngolang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=\ngolang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=\ngolang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 h1:O1cMQHRfwNpDfDJerqRoE2oD+AFlyid87D40L/OkkJo=\ngolang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2/go.mod h1:b7fPSJ0pKZ3ccUh8gnTONJxhn3c/PS6tyzQvyqw4iA8=\ngolang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=\ngolang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=\ngolang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=\ngolang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=\ngopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs=\ngopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI=\ngopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=\ngopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\nk8s.io/kms v0.34.3 h1:QzBOD0sk1bGQVMcZQAHGjtbP1iKZJUyhC6D0I+BTxIE=\nk8s.io/kms v0.34.3/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM=\n"
  },
  {
    "path": "hack/boilerplate.go.txt",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n"
  },
  {
    "path": "hack/ci-common.sh",
    "content": "export_artifacts() {\n  [ -n \"${ARTIFACTS:-}\" ] || return 0\n\n  mkdir -p \"$ARTIFACTS\"\n  cluster_name=sharding\n  echo \"> Exporting logs of kind cluster '$cluster_name'\"\n  kind export logs \"$ARTIFACTS\" --name \"$cluster_name\" || true\n\n  echo \"> Exporting events of kind cluster '$cluster_name'\"\n  export_events\n}\n\nexport_events() {\n  local dir=\"$ARTIFACTS/events\"\n  mkdir -p \"$dir\"\n\n  while IFS= read -r namespace; do\n    kubectl -n \"$namespace\" get event --sort-by=lastTimestamp >\"$dir/$namespace.log\" 2>&1 || true\n  done < <(kubectl get ns -oname | cut -d/ -f2)\n}\n"
  },
  {
    "path": "hack/ci-e2e-kind.sh",
    "content": "#!/usr/bin/env bash\n\nset -o nounset\nset -o pipefail\nset -o errexit\n\nsource \"$(dirname \"$0\")/ci-common.sh\"\n\n# test setup\nmake kind-up\nexport KUBECONFIG=$PWD/hack/kind_kubeconfig.yaml\n\n# export all container logs and events after test execution\ntrap '{\n  export_artifacts\n  make kind-down\n}' EXIT\n\n# deploy and test\nmake up SKAFFOLD_TAIL=false\nmake test-e2e GINKGO_FLAGS=\"--github-output\"\n"
  },
  {
    "path": "hack/config/README.md",
    "content": "# dev\n\nThis directory hosts manifests of components for the development setup.\nManifests of the sharding components are contained in [`config`](../../config).\nI.e., this directory should host only \"internal\" manifests that are not supposed to be reused outside of this repository.\n"
  },
  {
    "path": "hack/config/cert-manager/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- https://github.com/cert-manager/cert-manager/releases/download/v1.19.3/cert-manager.yaml\n\npatches:\n# lower the webhook timeouts to make the webhooks compliant with gardener's requirements\n- path: patch-validatingwebhook.yaml\n- path: patch-mutatingwebhook.yaml\n"
  },
  {
    "path": "hack/config/cert-manager/patch-mutatingwebhook.yaml",
    "content": "apiVersion: admissionregistration.k8s.io/v1\nkind: MutatingWebhookConfiguration\nmetadata:\n  name: cert-manager-webhook\nwebhooks:\n- name: webhook.cert-manager.io\n  timeoutSeconds: 15\n"
  },
  {
    "path": "hack/config/cert-manager/patch-validatingwebhook.yaml",
    "content": "apiVersion: admissionregistration.k8s.io/v1\nkind: ValidatingWebhookConfiguration\nmetadata:\n  name: cert-manager-webhook\nwebhooks:\n- name: webhook.cert-manager.io\n  timeoutSeconds: 15\n"
  },
  {
    "path": "hack/config/cert-manager/resources/cluster-issuer.yaml",
    "content": "apiVersion: cert-manager.io/v1\nkind: ClusterIssuer\nmetadata:\n  name: letsencrypt-http01\nspec:\n  acme:\n    email: null@timebertt.dev\n    server: https://acme-v02.api.letsencrypt.org/directory\n    privateKeySecretRef:\n      name: http01-timebertt-dev\n    solvers:\n    - http01:\n        ingress:\n          ingressClassName: nginx\n"
  },
  {
    "path": "hack/config/cert-manager/resources/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- cluster-issuer.yaml\n"
  },
  {
    "path": "hack/config/certificates/host/config.json",
    "content": "{\n  \"signing\": {\n    \"default\": {\n      \"expiry\": \"43800h\"\n    },\n    \"profiles\": {\n      \"server\": {\n        \"usages\": [\n          \"signing\",\n          \"key encipherment\",\n          \"server auth\"\n        ],\n        \"expiry\": \"43800h\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "hack/config/certificates/host/generate.sh",
    "content": "#!/usr/bin/env bash\n\nif ! command -v cfssl &>/dev/null ; then\n  echo \"cfssl not found, install it from https://github.com/cloudflare/cfssl\"\n  exit 1\nfi\n\ncd \"$(dirname \"$0\")\"\n\nrm -f *.pem\n\ncfssl gencert -config config.json -initca webhook-ca.json | cfssljson -bare webhook-ca\n\ncfssl gencert -config config.json -ca=webhook-ca.pem -ca-key=webhook-ca-key.pem -profile=server webhook-server.json | cfssljson -bare webhook-server\n\nrm *.csr\n"
  },
  {
    "path": "hack/config/certificates/host/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nnamespace: sharding-system\n\ngeneratorOptions:\n  disableNameSuffixHash: true\n\nsecretGenerator:\n- name: webhook-ca\n  options:\n    annotations:\n      cert-manager.io/allow-direct-injection: \"true\"\n  files:\n  - ca.crt=webhook-ca.pem\n"
  },
  {
    "path": "hack/config/certificates/host/webhook-ca-key.pem",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nMIIJKQIBAAKCAgEAsYRPd2BqRLB8TX/5bWZgZzRHihzB49P3t88lkfzbkinOFSWr\nIkQNnC1LOmCim39S0Un6ucEcyIZVDpCHvWyn7+YTmph+hWqccUNS+cmC3S9rt021\n/Ejg7/Lw7s7vNyxe4WsWSZWfx1+6aanUSNklvhDJ4fvveJx3qfKW+5sgdmVKXZk4\n7EcmFVMpY64y9yyju6KvaZd8M4YO7DvkfcLVnuXUWjFTzU8nNFvO8XoyLmRAcNOb\nA3Tf1Zy+HmJmnZo3hwgVOms2HRqRgbsOVYUOH67i2salfieDEN6KSTyieAbYvxIt\nR8VlhmcLjDlCFCdk0m3em6b8nroCw7wMUHCjJxvpDpkj4qEq6j+SZe/rSXCoRnyn\nuRBAFaCvqmpuep/djx3THF2wlS0TFCglubhmdxFxXYFhxKQDh5upvxWObBQb9X/F\nYr/rQlwez/v0G9LgxAVp1b96pnU4qE6xRmWkaRVrK7cbubLraqQ2S4XF8/mmoZZN\nfAqMbd+LJucUlBHdT0Q2QmmkxysLNbnlfMEplVXU0eA8LFa43raRLh8Z7mhiuSC+\nWhTI5UCF2OxIqFVgE0kYi3PA+pT8DcOb2KzytAZpHsBOTwwHoHjsyYpxYpsIvPhN\nSuWdv9AjOC7nmDzfM8N9WDPelg8tXC8XX330RbI5457Naj1HImZvTZd1TocCAwEA\nAQKCAgEAhQLQ0HAL8GAVI7TqXlDBl1MS76fQmDdxe+bZDeRbWc+9PRc2fbxkPkup\n/Jn//WeP1IYMOjc6q/4LqZgePY823oiU09fDpZBWnH+HouadCcLIgVbXL6wj72cn\npKilkb/LcDhfQM++IxPVh+rax6L9psbJnmy56LPE7jB5dRmtX0lSSYPPpStCm+Pu\nNWSHh7GJFcU2jnYVeD3Q3K2b7aeZjTBExzgCxOm0RIUuML4Q77Xqmx/THOnr9hE2\nW2n73cd6J9GkpltC9te7g2t3uBi0loTiMm95/Wb5zCATmgC29BydN74U85wzEFwR\nyQX2P0etQgdVL2gWDZDvFV7IE1XyyNDMB0fX357CmoFPC8HceKzIbE6sfRqawyXI\nT+Jj910uf7Sep37BOFdOTbJW42nuMtdnAnSPJYb0xu8pAGlamffj64Mh65WA/HLX\nilWemp7ymrSVkHgmgQ09dXw/5xlTFgrO7wOEArK97FRQCg75zKxxGHR59AKnpcQe\nRKfmhHEHyJXPP3xEdq50G26xlbEAE45eXx1qsdPWZK3jKmUZhZvu6PuO42x7qU2I\nLz4HY2HRH4XGXmnbW6GQc88AJEys1b/83CYIKEgaXsxa6x5TB3hT0YnzCgffZ4xm\nvspLiQ8oVcAAgXQ68IWAZFP1+3ZFgBW2ZJfbOBFFP6FchXH4UfECggEBAMYdG3y7\nwu92E6/XQLSUaj8jFlljKrAjmBbp2+V7FLzXoQozgIOtGS3A47JALkY5D+k2rhEt\ntQ+3R3k33YTZ5PoS9r1fGArtMqupUtsyrNAWz4e4GBwZDW8T89QC9enXMNiFg8kz\nRwebxKYz+oiqBn/Bq8UrbppsHUTmeMOODjXUq2X6CL+BD5+vgfav1bOQIZ2yotYF\nR3B5s0qag1OlNpbFIX7r1blHNXGrvVHhwC527HObslmp8efZL5wg3P/aDQ6NQN08\nkpmEVbq3ruPfqNut3yuUOW0hr+S+5q66ik+qxN406/zAHtpbuea4Jh5rJibjv9PT\nza8nPUJP/i1QeRMCggEBAOVijxdIBg1igSYNF3F+NTx2WHYiA7rFDkENGrZEvwmE\nq0Ifml0cmzjEbSjqUkC3ZzDE7hUexQeiJNv+a86vXBm+aFpLcKbZ6cJEb86vL6bf\noiW2+CcdMbMQHpR9UEdzGNLYR6DnTMaQA/w2umJXCXBFoR1pHdCSi2kLaw3lHBCf\nmzdfIvgDxqBqXMKhfbWUrH/Pc+hUXPejCqkS2SuL2b/N91V1uiaQ47xeXOxvDY5D\n6B/u1Cia0O6NGHDXSrmczhAg3jyhc8ttDuGQnpyHH3tA1RLxHu0oxLxN+o9K6JtW\n9fUxOgzJIcJtAmbuIbbcwxuSueabJgZoSp5JtdSxVz0CggEACiLJGjudAJVg8nkn\n1VVWjj5kUVRyhap8iIeUeYwvhm3dzmDOLW54wE+DFsaT14Hp33utsjFNdy1gWcJS\n8g4X2feIai3oU/7IveGe3JoeH1NbcM0pZp6dglZZ/jncjQc2d411LaES/D+q8vnr\n0nwocvbcq+zJ7tqjMLg963tkHLrxvfjp46pdu0TGeHGMlHBGWAQgsqR4gDepxaJc\nH7ZvMY2KZiz4tU8AW/12ZS8Qnw/0jwGjQVUhjEQfXHSN+gUU7+6oJ+mGcpZDsJbf\nOsdho0OlDFy8B2pWznQ55yyiEOtiwR+iBz9pFLDmtPgs8xd2Tz0Nvm+ysUhnqPHg\nxj68wwKCAQA7MYPbbiqhqZnKR/aUwwzZ3XBWi9CKke9rugX6oyLpQeMv3Rfoj0k/\nDPFebZlsOefXHfqSWK5fmegJHU6Ut4v82LX1FyKq6/D2wNJZc7vIRE2DjgPblB0P\nKEm759qflYQCZO2XCBk35FIi87yFRBCbeFxrSoT3Hdn78YZev5DOeWGEmHhdqBvJ\nqajmUOYvxX3+PXqbqamT/e7yUnrYUe6PIIeC9i5jZWBfa7pvCPlmjP+JvgfhspHX\n/XEhLW2LGHvUjabL3p4TEMGWU8uaeQQWulRB3xcr/ClIrpbKA3qjG329GEbypbSg\nh6DnDuyEU9PFecefSso1PRSEZGEX0evBAoIBAQC8MdTBttGMsLWvnD0HsV473yTj\njo0lyLSSEsTqnYla/7Ia1pqV4d18fPufV/vnz8Dy6ZyGrtmSAsQrZbEbRVBLW1kD\nilfL/ThQfsBHVxtRGpFB4kpPHJlyNETUD7HDwnuqIS/iODgltZXQAqRjN5ZcaHMd\nF4nT9Ua/Emwv8H/ibC16yBaJQ2jfDa4pD+gLnxtHblFeDPfu5fOiZL5Zm8ksh3u3\nuiHiPmyPKPT/aYRwyynvyJVdhWWI2nG+MhqdAIQzdmj7IEvLsyHuo/Mz2J+dOTrh\n+xNR37kYcH7RWwzxCBk4Wzx4prZ1e7UD82whBxYnUodJuJYu3PjKztC2LBpC\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "hack/config/certificates/host/webhook-ca.json",
    "content": "{\n  \"CN\": \"sharding:sharder\",\n  \"key\": {\n    \"algo\": \"rsa\",\n    \"size\": 4096\n  }\n}\n"
  },
  {
    "path": "hack/config/certificates/host/webhook-ca.pem",
    "content": "-----BEGIN CERTIFICATE-----\nMIIFBjCCAu6gAwIBAgIUel12x8tnTJwEPcuKhb8gxDzNL8UwDQYJKoZIhvcNAQEN\nBQAwGzEZMBcGA1UEAxMQc2hhcmRpbmc6c2hhcmRlcjAeFw0yMzExMTAxMzA3MDBa\nFw0yODExMDgxMzA3MDBaMBsxGTAXBgNVBAMTEHNoYXJkaW5nOnNoYXJkZXIwggIi\nMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCxhE93YGpEsHxNf/ltZmBnNEeK\nHMHj0/e3zyWR/NuSKc4VJasiRA2cLUs6YKKbf1LRSfq5wRzIhlUOkIe9bKfv5hOa\nmH6FapxxQ1L5yYLdL2u3TbX8SODv8vDuzu83LF7haxZJlZ/HX7ppqdRI2SW+EMnh\n++94nHep8pb7myB2ZUpdmTjsRyYVUyljrjL3LKO7oq9pl3wzhg7sO+R9wtWe5dRa\nMVPNTyc0W87xejIuZEBw05sDdN/VnL4eYmadmjeHCBU6azYdGpGBuw5VhQ4fruLa\nxqV+J4MQ3opJPKJ4Bti/Ei1HxWWGZwuMOUIUJ2TSbd6bpvyeugLDvAxQcKMnG+kO\nmSPioSrqP5Jl7+tJcKhGfKe5EEAVoK+qam56n92PHdMcXbCVLRMUKCW5uGZ3EXFd\ngWHEpAOHm6m/FY5sFBv1f8Viv+tCXB7P+/Qb0uDEBWnVv3qmdTioTrFGZaRpFWsr\ntxu5sutqpDZLhcXz+aahlk18Coxt34sm5xSUEd1PRDZCaaTHKws1ueV8wSmVVdTR\n4DwsVrjetpEuHxnuaGK5IL5aFMjlQIXY7EioVWATSRiLc8D6lPwNw5vYrPK0Bmke\nwE5PDAegeOzJinFimwi8+E1K5Z2/0CM4LueYPN8zw31YM96WDy1cLxdfffRFsjnj\nns1qPUciZm9Nl3VOhwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/\nBAUwAwEB/zAdBgNVHQ4EFgQUIPap7bhHigezp3QQ6oB1q9+rAzYwDQYJKoZIhvcN\nAQENBQADggIBAIzWfFXq8kmge+Bx+0L9zMb2a7vKsm8fX92/e3HwjCBg5uxwlebR\ngaQeK00O0+y0ozUaQ2fdxwQxH2i/hMEykvhpoAkPoMasirNVQ/FO7dF4cJ2NGwC0\nxsVWS+GmoUtNfU+AACitFVnbqRc9mYgb5xYEz+3AMvvsto3CHEVvRAKzWAmRW0wV\nM2dwq43Tri3UJ93SxsqIzKsOkWlfZV+2PBB6gxBdvSfLlZbo4TlIUwUdYBCUucBt\ne8i4g5SkYuLlBfRdtvDA5NKKsfxpqNAmHnpfUWyHkRyHngV6zB2xtRJ2K4VYGHDE\nmj02gj3Xb3HonCZuCLVXTAMAvLNUxpaQ7QjhCvMBwVOwQyiaAy2oy/EIqq90vaOF\ny07GKu/xl70B6mw7+T73YwlqphBnqdWY/u10VkqVRa1xBvhIgR7ISdjVWq5l2tYy\nw7PU1JEXPpJe5e54DQlkF6KFN3qLvwwKh34jtuElbxCrZ4Jft3GTR9eN7AEY5RUf\nQ7idZjQne1VX664kANnuFcEuTWyyDVJMsNBQXLcKMFFtigANaW57Ev15f7Z89Lom\nTOShtPrnGEUNYf44Xj28iMiae7RmRC/MhMIQGkOij+CmjuedpbkxZlFq6Y0ErHt1\nOKEdbfGvK/ffTMvuMk8zjEvXJXrTIYxqYsxow0LraaenDGLnNRy+OjH6\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "hack/config/certificates/host/webhook-server-key.pem",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nMIIJKAIBAAKCAgEAnDCsNJ5AoV5lrrsOAtzvDn7tZsqqM0e68p6UGPijBcmPS1Qj\nVRsbHyjWnd/L3bAJSOu7pwu3gkr3HLyPrrrRLobCzMnAVt1+X4qJnIdGYuOZVJfg\nLgmyeh8eWgeVyxAbObXkQ19LztDDrayMc8IyRyCQzSoZ6OJUWbTfHkJSQRvxowUt\nOvOF1zgg5qmLL5jiQNXSfpmWwqhXdmcuHNtlau0jhma2HXBPkVEidQvPRiaMYBNb\noHTzjAFw3R72mHmvOHhC0hdkF5q2A4CC9TvnIdf6fQZY5zZrWMWvrEvJBqX3k6jz\nQbwD3EnE5MJh56WIMESdo69xeeJZwaprmDr8Qf56uJqHcNwIqHPpusKu2Jceh5A+\npXo0OnBic6/sThCEvJ1luudTa7zKGiOaBlkVJ6PDD+v56j7/SXIx8jIdtgBStcX9\neUDnUHgNVSmrOzns5pn0EsYXni6UdHYtGsnSrAqLs967vsHw2U3if7EyoxbE4jdn\nGCJwUmDADu67CKGH0gopxn71ymAiV51oSO6IC7qFnurWwCyXLCvKN4KEFpQERKX6\niSflz7XKka604qXKXUGB8obq19+8MlVHOtq1OCtbYIDZmueBYZglp7p6yAVIinqw\nkimkmvCRrzn2B5YssoVSmWJCvoC7a6+9rYK+63nXHNRtZzf9istGPSJjRUUCAwEA\nAQKCAgA8mTnG9HtY4HoND/AAtl1dv2s2TX05hiQHS/VjttvxO+GHtW4779dXAI48\nFH9RVKJVk3hr+ETLnXBAyvvoK/1K0ugzcjdYvHjycpqvi2CIr4tm4cINup9veDFb\ndsPsVCRsAKE+bnPIGwFAmciohPji1cS4hRQmYeGeKGnEoLCvKDtZJ4ID9EXCWbmS\nJMemwOdPhmYzzj1K6ut8Oc4PTiQMF1OIKsOPqmqEk/kNdnaF3iDqibgsChQQBuMW\nN5QvVk7gVvB9+KtR6SmjNDIbGZG0dMpvxY2qr1d4ysI80+570Nq8hHlU0LCiwFBO\n/QflSzkKmSScRE5/no16cTdrib8i9HWT/ejlAfhN/FpD8jeccU26UPaoKyGQgvHV\nYceIt/o8NQQYO9/Vwc+8kKFAyjyI5jaW1Cjdp0ImZ7MK40yKYpFw3EHCChlOBh97\nB6IEhGAyqU93ADUxJZ/KeEG4cxSPzZtjGBrSMTbWyLUAYeUI8miVWMd2NvacLUs9\nPPil4jgLl9lhpG81BHe1YvQ+PKaKLoQWmaIPAe3Wb5aKnwX++nbowrNLYETHCQ/J\nwklZmk+2A+oPjEkrp8GoTyAcD9cJAXHxH9/6itdUhtA9lxAKKlpZNNMlMLWbzEJn\n/LOof/2ob3aws/6y3ETNbDen/cVjyk6gG9gO97AYUP++zxmMZQKCAQEAwwkgR2VO\n2UghqEQPigMhxy3VVKfhOp9ebS7bYvtZNstEE9WOTUDdQudTk0BFE4HL/3KbghLI\nRcSEUtZxYJQSfXu4EHtEg/EDYaoPnWhcDxj1Tn4O4m58tTEkMT/42AzPlnAESoAB\n5LO6SV/sBtXP+CLmga1Y43Op2aimM1ewjJWqJl9IYTVp8bDZqU66JelJT8GHZ6tY\npfgAKSWyz+RX8hdtuuwxBNcktdJgeuH6zO4EwgCyzd5xrMyG1J8AM557ReiRntkP\nSbhq9THQFfMJld7Guo7YNTX6BhYyl04821THHd+oCITw7OY23aH0oJgIE9cllzBZ\nKkwWOw5XubX7vwKCAQEAzQMalIGZTFilHSKj7/QqyW8+xo7urV211uYRV6eLnTx2\n1+jcbizWfH0N8Uwt1Jvk8TWDIrwndZoeIrINXWiZPZf1+EDkRAgMwinfS7bsrLVd\nlNsQoPAWMydoZEvgM7+mfLbjPkX2wUy03WNI0htk4+uxnZMD75y/r2ZRKRxV7bi4\nNMS6kQrGYjaivtqMz7hqHBd0O1PUyMpcMREMuKiawWYjERKIJU+dI0empTWAyLVb\n5Q93IkMjxVKEa65jjLB/ngvloNxjCK28WelG5Dbdc2zUa+OQ8GguD6Q1p5UQNoHv\nKIMuS6mJm8UUl746cdbPv6lgYAByfBat6PKE6xrP+wKCAQBLAxmNHCPFYf6/7t1j\nIW0+ZBxmoOL5Xw48RAdQ/IcFkgwu7LX8dHQlJT95pQBsTkGdkADLeFnaq4iRK7UT\nhh/Ob2UNwbtKW8oHKBc1XUv66oh+lfE3mXMRZUMcRhR5VAQLQi4EUVNpGM8PJXtr\n7ZQ9RX8OZROI95VeB4VUvedDStTUSVVXPenvcStl+MeTiTQPHsnrT3Wa79Vv/fXW\nC2bfz67+c5Uu3WhbHfzJhlylsO3Xh9k9YM6rvUYmRLkZIV0cOCS5yZYdrnZEs9Hq\nfz0yjSo12nbBkG8HJEZ09zxkxyiGDt1b2XWoR6rWd1HU6mRA7UCh85B3uifastt+\nq8WVAoIBAQCxAWUJo3vANykYJrh0jNQEZ1BED1Rzyt0dVjbS/43DjFjvwdXQKlZl\n1XMcSzGmx5K70AARFXLcTtyGCEURySXF0FZGqYBsXKbnXU+2B5IA6/aIdzu8OI5y\nTCwNrJU/GNGeDCnXsoCCFMB0BSzye0R4pR8NdcmIMEYwIp8gZ56pSTuCE/khEbSH\nR7TsI7ZAAnFbH8TzFEY7trwygQ4CwVAcexr7uoxh6oM52rs/GRrAMBXPh7LMmjtg\nOwaqEj9RUXJd+tegM6gt7hMZbhgPIm/BIM2m+SxC5TAfwR+yOTluVnEvAVQPb6mo\nHFjTSyMa9uUYDh1vxfMSwGIXJo0skFHRAoIBAEEX7v0NaSZX2m7WY/prxGqIQ/MD\nItf6Rdspl/CdeU7xHezzCKGgLdvlZKM24XnZZO/leZG/H/BKPkKoPG4k/QxsZb3B\nS1WJD1DineQyjw4GsLgMaOT7rYWVrdypDKcuwVU+drsoED5P19Wr2GnetnzoYEYw\nLjSaoCDvfwPszesS8qnA/YjfKbF9PSANbaj/fK/Z8w1ZS2mVF52arKiAbpYJgK7H\nY4EfYHcZjk4vJOMZOlgio/6H0CyLvc2pAfXLVN0Ho0RtTy0KgwXsxCx2gw+BU5xK\nB9tKU0Q+8sWmjUaoj3IGxKjGkJG/a8M9H3jAVnd8NpI9A0if5LXVHTlfXfo=\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "hack/config/certificates/host/webhook-server.json",
    "content": "{\n  \"CN\": \"sharding:sharder:webhook\",\n  \"key\": {\n    \"algo\": \"rsa\",\n    \"size\": 4096\n  },\n  \"hosts\": [\n    \"localhost\",\n    \"host.docker.internal\",\n    \"sharder.sharding-system\",\n    \"sharder.sharding-system.svc\",\n    \"sharder.sharding-system.svc.cluster.local\"\n  ]\n}\n"
  },
  {
    "path": "hack/config/certificates/host/webhook-server.pem",
    "content": "-----BEGIN CERTIFICATE-----\nMIIF1TCCA72gAwIBAgIURVQwgiERbtUeNjwxwSrp4jIAY+UwDQYJKoZIhvcNAQEN\nBQAwGzEZMBcGA1UEAxMQc2hhcmRpbmc6c2hhcmRlcjAeFw0yMzExMTAxMzA3MDBa\nFw0yODExMDgxMzA3MDBaMCMxITAfBgNVBAMTGHNoYXJkaW5nOnNoYXJkZXI6d2Vi\naG9vazCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJwwrDSeQKFeZa67\nDgLc7w5+7WbKqjNHuvKelBj4owXJj0tUI1UbGx8o1p3fy92wCUjru6cLt4JK9xy8\nj6660S6GwszJwFbdfl+KiZyHRmLjmVSX4C4JsnofHloHlcsQGzm15ENfS87Qw62s\njHPCMkcgkM0qGejiVFm03x5CUkEb8aMFLTrzhdc4IOapiy+Y4kDV0n6ZlsKoV3Zn\nLhzbZWrtI4Zmth1wT5FRInULz0YmjGATW6B084wBcN0e9ph5rzh4QtIXZBeatgOA\ngvU75yHX+n0GWOc2a1jFr6xLyQal95Oo80G8A9xJxOTCYeeliDBEnaOvcXniWcGq\na5g6/EH+eriah3DcCKhz6brCrtiXHoeQPqV6NDpwYnOv7E4QhLydZbrnU2u8yhoj\nmgZZFSejww/r+eo+/0lyMfIyHbYAUrXF/XlA51B4DVUpqzs57OaZ9BLGF54ulHR2\nLRrJ0qwKi7Peu77B8NlN4n+xMqMWxOI3ZxgicFJgwA7uuwihh9IKKcZ+9cpgIled\naEjuiAu6hZ7q1sAslywryjeChBaUBESl+okn5c+1ypGutOKlyl1BgfKG6tffvDJV\nRzratTgrW2CA2ZrngWGYJae6esgFSIp6sJIppJrwka859geWLLKFUpliQr6Au2uv\nva2Cvut51xzUbWc3/YrLRj0iY0VFAgMBAAGjggEHMIIBAzAOBgNVHQ8BAf8EBAMC\nBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU\nY2OhGXVByKhfKePAFNjN3oE5b6UwHwYDVR0jBBgwFoAUIPap7bhHigezp3QQ6oB1\nq9+rAzYwgY0GA1UdEQSBhTCBgoIJbG9jYWxob3N0ghRob3N0LmRvY2tlci5pbnRl\ncm5hbIIXc2hhcmRlci5zaGFyZGluZy1zeXN0ZW2CG3NoYXJkZXIuc2hhcmRpbmct\nc3lzdGVtLnN2Y4Ipc2hhcmRlci5zaGFyZGluZy1zeXN0ZW0uc3ZjLmNsdXN0ZXIu\nbG9jYWwwDQYJKoZIhvcNAQENBQADggIBACya1KVsYrn2ppv4/OIHduXyyHYdB9KU\nqnp98zAriLcPAgn1n9PuNYpfoyCP1amvKx24oUEW4NnPED3a54AeDOdInI2j7Xmb\nNVgjGBAta7ye4oZTuiB+MfBgpaSlH8ML6B6j7B/LQbQLpbSp/ZFNj73o56XAr/fi\nKQlbnn1fmGKlNywXDOnMpYhrYKMlB0KJ+bhTlD8gueBhYTRH4O5Kw1n6T2XUiZNf\nnK+rXMdCnXgq6HWWsRlOWWXFsxcDK58sEzw+uhQD/9Yu5jpcJV13K/MEK3q4L5pP\n4NDq7zItfF5GgKl9AZwXKTSJ8Ij3bjgb1HJteaM9Ul+Gu2NWd1BooQi7RBbtPOjN\nnoi1JL2tJELG4bl7vUPvP+l/005cgCdqwPch4Eq+am3i0AT4rPutWnFlcZfc4lHm\nJMku6EvtS6aMQeipQmG91tHumtgNAcN5YlkHrDqL2FiOHYAo/XXjwrH3rL27s2CT\nOfpGcBS4wJsMUabdqPpU0mAXKcWFFwlv4e8hNiB8JF6ty8weN5AYymCAE/66mZgI\nSQ/0FYmSRFLg5g51bPHEEUig3UsI68pxJW3DQQSOYmHwpRPMHYV8lI8CrrAHtPp8\neN8f8jBVkJfDLZ/LpeE6mH0OmtEbA+29kfYt1pdWdTAqrcmaF3d5j9wF28mExMXw\nd92Evgc96uZh\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "hack/config/checksum-controller/controller/deployment.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: checksum-controller\nspec:\n  replicas: 3\n  template:\n    spec:\n      automountServiceAccountToken: true\n      securityContext:\n        runAsNonRoot: true\n      containers:\n      - name: checksum-controller\n        image: checksum-controller:latest\n        args:\n        - --zap-devel\n        env:\n        - name: DISABLE_HTTP2\n          value: \"true\"\n        securityContext:\n          allowPrivilegeEscalation: false\n        resources:\n          requests:\n            cpu: 25m\n            memory: 50Mi\n      serviceAccountName: checksum-controller\n      terminationGracePeriodSeconds: 10\n"
  },
  {
    "path": "hack/config/checksum-controller/controller/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nnamespace: default\n\nlabels:\n- includeSelectors: true\n  pairs:\n    app.kubernetes.io/name: controller-sharding\n    app.kubernetes.io/component: checksum-controller\n\nimages:\n- name: checksum-controller\n  newName: ghcr.io/timebertt/kubernetes-controller-sharding/checksum-controller\n  newTag: latest\n\nresources:\n- ../controllerring\n- deployment.yaml\n- rbac.yaml\n- serviceaccount.yaml\n"
  },
  {
    "path": "hack/config/checksum-controller/controller/rbac.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  name: sharding:checksum-controller\nrules:\n- apiGroups:\n  - coordination.k8s.io\n  resources:\n  - leases\n  verbs:\n  - get\n  - create\n  - update\n- apiGroups:\n  - \"\"\n  resources:\n  - events\n  verbs:\n  - create\n  - patch\n- apiGroups:\n  - \"\"\n  resources:\n  - secrets\n  verbs:\n  - get\n  - list\n  - watch\n  - patch\n- apiGroups:\n  - \"\"\n  resources:\n  - configmaps\n  verbs:\n  - get\n  - list\n  - watch\n  - create\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: sharding:checksum-controller\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: sharding:checksum-controller\nsubjects:\n- kind: ServiceAccount\n  name: checksum-controller\n"
  },
  {
    "path": "hack/config/checksum-controller/controller/serviceaccount.yaml",
    "content": "apiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: checksum-controller\nautomountServiceAccountToken: false\n"
  },
  {
    "path": "hack/config/checksum-controller/controllerring/controllerring.yaml",
    "content": "apiVersion: sharding.timebertt.dev/v1alpha1\nkind: ControllerRing\nmetadata:\n  name: checksum-controller\nspec:\n  resources:\n  - group: \"\"\n    resource: secrets\n    controlledResources:\n    - group: \"\"\n      resource: configmaps\n  namespaceSelector:\n    matchLabels:\n      kubernetes.io/metadata.name: default\n"
  },
  {
    "path": "hack/config/checksum-controller/controllerring/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- controllerring.yaml\n- sharder_rbac.yaml\n"
  },
  {
    "path": "hack/config/checksum-controller/controllerring/sharder_rbac.yaml",
    "content": "# These manifests grant the sharder controller permissions to act on resources that we listed in the ControllerRing.\n# We need to grant these permissions explicitly depending on what we configured. Otherwise, the sharder would require\n# cluster-admin access.\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: sharding:controllerring:checksum-controller\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - configmaps\n  - secrets\n  verbs:\n  - list\n  - patch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: sharding:controllerring:checksum-controller\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: sharding:controllerring:checksum-controller\nsubjects:\n- kind: ServiceAccount\n  name: sharder\n  namespace: sharding-system\n"
  },
  {
    "path": "hack/config/external-dns/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nnamespace: external-dns\n\nimages:\n- name: registry.k8s.io/external-dns/external-dns\n  newTag: v0.19.0\n\nresources:\n- namespace.yaml\n- https://github.com/kubernetes-sigs/external-dns//kustomize?ref=v0.19.0\n\npatches:\n- path: patch-deployment.yaml\n# Add permissions for endpointslices needed for https://github.com/kubernetes-sigs/external-dns/pull/5493.\n# TODO: drop this patch once https://github.com/kubernetes-sigs/external-dns/pull/5573 has been released.\n- target:\n    kind: ClusterRole\n    name: external-dns\n  patch: |\n    - op: add\n      path: /rules/-\n      value:\n        apiGroups: [\"discovery.k8s.io\"]\n        resources: [\"endpointslices\"]\n        verbs: [\"get\",\"watch\",\"list\"]\n"
  },
  {
    "path": "hack/config/external-dns/namespace.yaml",
    "content": "apiVersion: v1\nkind: Namespace\nmetadata:\n  name: external-dns\n"
  },
  {
    "path": "hack/config/external-dns/patch-deployment.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: external-dns\n  namespace: default\nspec:\n  template:\n    spec:\n      containers:\n      - name: external-dns\n        args:\n        - --source=ingress\n        - --source=service\n        - --domain-filter=timebertt.dev\n        - --provider=google\n        - --log-format=json\n        - --google-project=$(GOOGLE_PROJECT)\n        - --google-zone-visibility=public\n        - --policy=sync\n        - --registry=txt\n        - --txt-owner-id=shoot--ixywdlfvei--sharding-2025a5e1-9ac9-471c-9ef0-0a2e70527e5f-ske\n        - --interval=1m\n        # ensure the records are not owned by short-lived acme solvers managed by cert-manager or website ingresses\n        - --label-filter=acme.cert-manager.io/http01-solver!=true,app!=website\n        env:\n        - name: GOOGLE_APPLICATION_CREDENTIALS\n          value: /etc/secrets/service-account/service-account.json\n        - name: GOOGLE_PROJECT\n          valueFrom:\n            secretKeyRef:\n              name: google-clouddns-timebertt-dev\n              key: project\n        volumeMounts:\n        - name: clouddns-credentials\n          mountPath: /etc/secrets/service-account\n          readOnly: true\n      volumes:\n      - name: clouddns-credentials\n        secret:\n          secretName: google-clouddns-timebertt-dev\n"
  },
  {
    "path": "hack/config/ingress-nginx/default/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nnamespace: ingress-nginx\n\nresources:\n- https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.14.3/deploy/static/provider/cloud/deploy.yaml\n\npatches:\n- path: patch_default_ingress_class.yaml\n- path: patch_controller_resources.yaml\n# Delete validation webhook for Ingresses.\n# We don't need or want validation for Ingress objects in the development and load testing setup. It results in high\n# latency for API requests and CPU waste during load tests.\n- patch: |\n    apiVersion: admissionregistration.k8s.io/v1\n    kind: ValidatingWebhookConfiguration\n    metadata:\n      name: ingress-nginx-admission\n    $patch: delete\n# This job fails if the ValidatingWebhookConfiguration does not exist. Drop it as well.\n# Note: we can't drop the ingress-nginx-admission-create job, which creates the webhook certificate. Without this,\n# the ingress-nginx-controller won't start.\n- patch: |\n    apiVersion: batch/v1\n    kind: Job\n    metadata:\n      name: ingress-nginx-admission-patch\n      namespace: ingress-nginx\n    $patch: delete\n"
  },
  {
    "path": "hack/config/ingress-nginx/default/patch_controller_resources.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: ingress-nginx-controller\n  namespace: ingress-nginx\nspec:\n  template:\n    spec:\n      containers:\n      - name: controller\n        resources:\n          requests:\n            cpu: 10m\n            memory: 256Mi\n"
  },
  {
    "path": "hack/config/ingress-nginx/default/patch_default_ingress_class.yaml",
    "content": "apiVersion: networking.k8s.io/v1\nkind: IngressClass\nmetadata:\n  name: nginx\n  namespace: ingress-nginx\n  annotations:\n    ingressclass.kubernetes.io/is-default-class: \"true\"\n"
  },
  {
    "path": "hack/config/ingress-nginx/kind/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../default\n\npatches:\n- path: patch_service_nodeport.yaml\n"
  },
  {
    "path": "hack/config/ingress-nginx/kind/patch_service_nodeport.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: ingress-nginx-controller\n  namespace: ingress-nginx\nspec:\n  ports:\n  - appProtocol: http\n    name: http\n    nodePort: 30888\n    port: 80\n    protocol: TCP\n    targetPort: http\n"
  },
  {
    "path": "hack/config/ingress-nginx/shoot/certificate.yaml",
    "content": "apiVersion: cert-manager.io/v1\nkind: Certificate\nmetadata:\n  name: webhosting-tls\nspec:\n  dnsNames:\n  - webhosting.timebertt.dev\n  issuerRef:\n    group: cert-manager.io\n    kind: ClusterIssuer\n    name: letsencrypt-http01\n  secretName: webhosting-tls\n  usages:\n  - digital signature\n  - key encipherment\n"
  },
  {
    "path": "hack/config/ingress-nginx/shoot/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nnamespace: ingress-nginx\n\nresources:\n- ../default\n- certificate.yaml\n\npatches:\n- path: patch_service.yaml\n- target:\n    group: apps\n    version: v1\n    kind: Deployment\n    name: ingress-nginx-controller\n    namespace: ingress-nginx\n  patch: |\n    - op: add\n      path: /spec/template/spec/containers/0/args/-\n      value: \"--default-ssl-certificate=ingress-nginx/webhosting-tls\"\n"
  },
  {
    "path": "hack/config/ingress-nginx/shoot/patch_service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: ingress-nginx-controller\n  namespace: ingress-nginx\n  annotations:\n    external-dns.alpha.kubernetes.io/hostname: webhosting.timebertt.dev\n"
  },
  {
    "path": "hack/config/kind-config.yaml",
    "content": "apiVersion: kind.x-k8s.io/v1alpha4\nkind: Cluster\nnodes:\n- role: control-plane\n  extraPortMappings:\n  # ingress-nginx\n  - containerPort: 30888\n    hostPort: 8088\n  kubeadmConfigPatches:\n  - |\n    apiVersion: kubelet.config.k8s.io/v1beta1\n    kind: KubeletConfiguration\n    maxPods: 250\n  - |\n    apiVersion: kubeadm.k8s.io/v1beta3\n    kind: ClusterConfiguration\n    controllerManager:\n      extraArgs:\n        kube-api-qps: \"800\"\n        kube-api-burst: \"1000\"\n"
  },
  {
    "path": "hack/config/kyverno/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- https://github.com/kyverno/kyverno/releases/download/v1.17.0/install.yaml\n\nconfigMapGenerator:\n- name: kyverno\n  namespace: kyverno\n  behavior: merge\n  options:\n    disableNameSuffixHash: true\n  literals:\n  # overwrite default namespaceSelector for webhook configs to exclude kube-system\n  # the second part makes gardeners care controller/webhook remediation happy\n  - >-\n    webhooks={\n      \"namespaceSelector\": {\n        \"matchExpressions\": [{\n          \"key\": \"kubernetes.io/metadata.name\",\n          \"operator\": \"NotIn\",\n          \"values\": [\"kyverno\", \"kube-system\"]\n        }, {\n          \"key\": \"gardener.cloud/purpose\",\n          \"operator\": \"NotIn\",\n          \"values\": [\"kube-system\"]\n        }]\n      }\n    }\n"
  },
  {
    "path": "hack/config/monitoring/crds/0alertmanagerConfigCustomResourceDefinition.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.18.0\n    operator.prometheus.io/version: 0.85.0\n  name: alertmanagerconfigs.monitoring.coreos.com\nspec:\n  group: monitoring.coreos.com\n  names:\n    categories:\n    - prometheus-operator\n    kind: AlertmanagerConfig\n    listKind: AlertmanagerConfigList\n    plural: alertmanagerconfigs\n    shortNames:\n    - amcfg\n    singular: alertmanagerconfig\n  scope: Namespaced\n  versions:\n  - name: v1alpha1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          AlertmanagerConfig configures the Prometheus Alertmanager,\n          specifying how alerts should be grouped, inhibited and notified to external systems.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: |-\n              AlertmanagerConfigSpec is a specification of the desired behavior of the\n              Alertmanager configuration.\n              By default, the Alertmanager configuration only applies to alerts for which\n              the `namespace` label is equal to the namespace of the AlertmanagerConfig\n              resource (see the `.spec.alertmanagerConfigMatcherStrategy` field of the\n              Alertmanager CRD).\n            properties:\n              inhibitRules:\n                description: |-\n                  List of inhibition rules. The rules will only apply to alerts matching\n                  the resource's namespace.\n                items:\n                  description: |-\n                    InhibitRule defines an inhibition rule that allows to mute alerts when other\n                    alerts are already firing.\n                    See https://prometheus.io/docs/alerting/latest/configuration/#inhibit_rule\n                  properties:\n                    equal:\n                      description: |-\n                        Labels that must have an equal value in the source and target alert for\n                        the inhibition to take effect.\n                      items:\n                        type: string\n                      type: array\n                    sourceMatch:\n                      description: |-\n                        Matchers for which one or more alerts have to exist for the inhibition\n                        to take effect. The operator enforces that the alert matches the\n                        resource's namespace.\n                      items:\n                        description: Matcher defines how to match on alert's labels.\n                        properties:\n                          matchType:\n                            description: |-\n                              Match operation available with AlertManager >= v0.22.0 and\n                              takes precedence over Regex (deprecated) if non-empty.\n                            enum:\n                            - '!='\n                            - =\n                            - =~\n                            - '!~'\n                            type: string\n                          name:\n                            description: Label to match.\n                            minLength: 1\n                            type: string\n                          regex:\n                            description: |-\n                              Whether to match on equality (false) or regular-expression (true).\n                              Deprecated: for AlertManager >= v0.22.0, `matchType` should be used instead.\n                            type: boolean\n                          value:\n                            description: Label value to match.\n                            type: string\n                        required:\n                        - name\n                        type: object\n                      type: array\n                    targetMatch:\n                      description: |-\n                        Matchers that have to be fulfilled in the alerts to be muted. The\n                        operator enforces that the alert matches the resource's namespace.\n                      items:\n                        description: Matcher defines how to match on alert's labels.\n                        properties:\n                          matchType:\n                            description: |-\n                              Match operation available with AlertManager >= v0.22.0 and\n                              takes precedence over Regex (deprecated) if non-empty.\n                            enum:\n                            - '!='\n                            - =\n                            - =~\n                            - '!~'\n                            type: string\n                          name:\n                            description: Label to match.\n                            minLength: 1\n                            type: string\n                          regex:\n                            description: |-\n                              Whether to match on equality (false) or regular-expression (true).\n                              Deprecated: for AlertManager >= v0.22.0, `matchType` should be used instead.\n                            type: boolean\n                          value:\n                            description: Label value to match.\n                            type: string\n                        required:\n                        - name\n                        type: object\n                      type: array\n                  type: object\n                type: array\n              muteTimeIntervals:\n                description: List of MuteTimeInterval specifying when the routes should be muted.\n                items:\n                  description: MuteTimeInterval specifies the periods in time when notifications will be muted\n                  properties:\n                    name:\n                      description: Name of the time interval\n                      type: string\n                    timeIntervals:\n                      description: TimeIntervals is a list of TimeInterval\n                      items:\n                        description: TimeInterval describes intervals of time\n                        properties:\n                          daysOfMonth:\n                            description: DaysOfMonth is a list of DayOfMonthRange\n                            items:\n                              description: DayOfMonthRange is an inclusive range of days of the month beginning at 1\n                              properties:\n                                end:\n                                  description: End of the inclusive range\n                                  maximum: 31\n                                  minimum: -31\n                                  type: integer\n                                start:\n                                  description: Start of the inclusive range\n                                  maximum: 31\n                                  minimum: -31\n                                  type: integer\n                              type: object\n                            type: array\n                          months:\n                            description: Months is a list of MonthRange\n                            items:\n                              description: |-\n                                MonthRange is an inclusive range of months of the year beginning in January\n                                Months can be specified by name (e.g 'January') by numerical month (e.g '1') or as an inclusive range (e.g 'January:March', '1:3', '1:March')\n                              pattern: ^((?i)january|february|march|april|may|june|july|august|september|october|november|december|1[0-2]|[1-9])(?:((:((?i)january|february|march|april|may|june|july|august|september|october|november|december|1[0-2]|[1-9]))$)|$)\n                              type: string\n                            type: array\n                          times:\n                            description: Times is a list of TimeRange\n                            items:\n                              description: TimeRange defines a start and end time in 24hr format\n                              properties:\n                                endTime:\n                                  description: EndTime is the end time in 24hr format.\n                                  pattern: ^((([01][0-9])|(2[0-3])):[0-5][0-9])$|(^24:00$)\n                                  type: string\n                                startTime:\n                                  description: StartTime is the start time in 24hr format.\n                                  pattern: ^((([01][0-9])|(2[0-3])):[0-5][0-9])$|(^24:00$)\n                                  type: string\n                              type: object\n                            type: array\n                          weekdays:\n                            description: Weekdays is a list of WeekdayRange\n                            items:\n                              description: |-\n                                WeekdayRange is an inclusive range of days of the week beginning on Sunday\n                                Days can be specified by name (e.g 'Sunday') or as an inclusive range (e.g 'Monday:Friday')\n                              pattern: ^((?i)sun|mon|tues|wednes|thurs|fri|satur)day(?:((:(sun|mon|tues|wednes|thurs|fri|satur)day)$)|$)\n                              type: string\n                            type: array\n                          years:\n                            description: Years is a list of YearRange\n                            items:\n                              description: YearRange is an inclusive range of years\n                              pattern: ^2\\d{3}(?::2\\d{3}|$)\n                              type: string\n                            type: array\n                        type: object\n                      type: array\n                  required:\n                  - name\n                  type: object\n                type: array\n              receivers:\n                description: List of receivers.\n                items:\n                  description: Receiver defines one or more notification integrations.\n                  properties:\n                    discordConfigs:\n                      description: List of Discord configurations.\n                      items:\n                        description: |-\n                          DiscordConfig configures notifications via Discord.\n                          See https://prometheus.io/docs/alerting/latest/configuration/#discord_config\n                        properties:\n                          apiURL:\n                            description: |-\n                              The secret's key that contains the Discord webhook URL.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          avatarURL:\n                            description: The avatar url of the message sender.\n                            pattern: ^https?://.+$\n                            type: string\n                          content:\n                            description: The template of the content's body.\n                            minLength: 1\n                            type: string\n                          httpConfig:\n                            description: HTTP client configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          message:\n                            description: The template of the message's body.\n                            type: string\n                          sendResolved:\n                            description: Whether or not to notify about resolved alerts.\n                            type: boolean\n                          title:\n                            description: The template of the message's title.\n                            type: string\n                          username:\n                            description: The username of the message sender.\n                            minLength: 1\n                            type: string\n                        required:\n                        - apiURL\n                        type: object\n                      type: array\n                    emailConfigs:\n                      description: List of Email configurations.\n                      items:\n                        description: EmailConfig configures notifications via Email.\n                        properties:\n                          authIdentity:\n                            description: The identity to use for authentication.\n                            type: string\n                          authPassword:\n                            description: |-\n                              The secret's key that contains the password to use for authentication.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          authSecret:\n                            description: |-\n                              The secret's key that contains the CRAM-MD5 secret.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          authUsername:\n                            description: The username to use for authentication.\n                            type: string\n                          from:\n                            description: The sender address.\n                            type: string\n                          headers:\n                            description: |-\n                              Further headers email header key/value pairs. Overrides any headers\n                              previously set by the notification implementation.\n                            items:\n                              description: KeyValue defines a (key, value) tuple.\n                              properties:\n                                key:\n                                  description: Key of the tuple.\n                                  minLength: 1\n                                  type: string\n                                value:\n                                  description: Value of the tuple.\n                                  type: string\n                              required:\n                              - key\n                              - value\n                              type: object\n                            type: array\n                          hello:\n                            description: The hostname to identify to the SMTP server.\n                            type: string\n                          html:\n                            description: The HTML body of the email notification.\n                            type: string\n                          requireTLS:\n                            description: |-\n                              The SMTP TLS requirement.\n                              Note that Go does not support unencrypted connections to remote SMTP endpoints.\n                            type: boolean\n                          sendResolved:\n                            description: Whether or not to notify about resolved alerts.\n                            type: boolean\n                          smarthost:\n                            description: The SMTP host and port through which emails are sent. E.g. example.com:25\n                            type: string\n                          text:\n                            description: The text body of the email notification.\n                            type: string\n                          tlsConfig:\n                            description: TLS configuration\n                            properties:\n                              ca:\n                                description: Certificate authority used when verifying server certificates.\n                                properties:\n                                  configMap:\n                                    description: ConfigMap containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key to select.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the ConfigMap or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  secret:\n                                    description: Secret containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              cert:\n                                description: Client certificate to present when doing client-authentication.\n                                properties:\n                                  configMap:\n                                    description: ConfigMap containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key to select.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the ConfigMap or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  secret:\n                                    description: Secret containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              insecureSkipVerify:\n                                description: Disable target certificate validation.\n                                type: boolean\n                              keySecret:\n                                description: Secret containing the client key file for the targets.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              maxVersion:\n                                description: |-\n                                  Maximum acceptable TLS version.\n\n                                  It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                enum:\n                                - TLS10\n                                - TLS11\n                                - TLS12\n                                - TLS13\n                                type: string\n                              minVersion:\n                                description: |-\n                                  Minimum acceptable TLS version.\n\n                                  It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                enum:\n                                - TLS10\n                                - TLS11\n                                - TLS12\n                                - TLS13\n                                type: string\n                              serverName:\n                                description: Used to verify the hostname for the targets.\n                                type: string\n                            type: object\n                          to:\n                            description: The email address to send notifications to.\n                            type: string\n                        type: object\n                      type: array\n                    msteamsConfigs:\n                      description: |-\n                        List of MSTeams configurations.\n                        It requires Alertmanager >= 0.26.0.\n                      items:\n                        description: |-\n                          MSTeamsConfig configures notifications via Microsoft Teams.\n                          It requires Alertmanager >= 0.26.0.\n                        properties:\n                          httpConfig:\n                            description: HTTP client configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          sendResolved:\n                            description: Whether to notify about resolved alerts.\n                            type: boolean\n                          summary:\n                            description: |-\n                              Message summary template.\n                              It requires Alertmanager >= 0.27.0.\n                            type: string\n                          text:\n                            description: Message body template.\n                            type: string\n                          title:\n                            description: Message title template.\n                            type: string\n                          webhookUrl:\n                            description: MSTeams webhook URL.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        required:\n                        - webhookUrl\n                        type: object\n                      type: array\n                    msteamsv2Configs:\n                      description: |-\n                        List of MSTeamsV2 configurations.\n                        It requires Alertmanager >= 0.28.0.\n                      items:\n                        description: |-\n                          MSTeamsV2Config configures notifications via Microsoft Teams using the new message format with adaptive cards as required by flows\n                          See https://prometheus.io/docs/alerting/latest/configuration/#msteamsv2_config\n                          It requires Alertmanager >= 0.28.0.\n                        properties:\n                          httpConfig:\n                            description: HTTP client configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          sendResolved:\n                            description: Whether to notify about resolved alerts.\n                            type: boolean\n                          text:\n                            description: Message body template.\n                            minLength: 1\n                            type: string\n                          title:\n                            description: Message title template.\n                            minLength: 1\n                            type: string\n                          webhookURL:\n                            description: MSTeams incoming webhook URL.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      type: array\n                    name:\n                      description: Name of the receiver. Must be unique across all items from the list.\n                      minLength: 1\n                      type: string\n                    opsgenieConfigs:\n                      description: List of OpsGenie configurations.\n                      items:\n                        description: |-\n                          OpsGenieConfig configures notifications via OpsGenie.\n                          See https://prometheus.io/docs/alerting/latest/configuration/#opsgenie_config\n                        properties:\n                          actions:\n                            description: Comma separated list of actions that will be available for the alert.\n                            type: string\n                          apiKey:\n                            description: |-\n                              The secret's key that contains the OpsGenie API key.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          apiURL:\n                            description: The URL to send OpsGenie API requests to.\n                            type: string\n                          description:\n                            description: Description of the incident.\n                            type: string\n                          details:\n                            description: A set of arbitrary key/value pairs that provide further detail about the incident.\n                            items:\n                              description: KeyValue defines a (key, value) tuple.\n                              properties:\n                                key:\n                                  description: Key of the tuple.\n                                  minLength: 1\n                                  type: string\n                                value:\n                                  description: Value of the tuple.\n                                  type: string\n                              required:\n                              - key\n                              - value\n                              type: object\n                            type: array\n                          entity:\n                            description: Optional field that can be used to specify which domain alert is related to.\n                            type: string\n                          httpConfig:\n                            description: HTTP client configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          message:\n                            description: Alert text limited to 130 characters.\n                            type: string\n                          note:\n                            description: Additional alert note.\n                            type: string\n                          priority:\n                            description: Priority level of alert. Possible values are P1, P2, P3, P4, and P5.\n                            type: string\n                          responders:\n                            description: List of responders responsible for notifications.\n                            items:\n                              description: |-\n                                OpsGenieConfigResponder defines a responder to an incident.\n                                One of `id`, `name` or `username` has to be defined.\n                              properties:\n                                id:\n                                  description: ID of the responder.\n                                  type: string\n                                name:\n                                  description: Name of the responder.\n                                  type: string\n                                type:\n                                  description: Type of responder.\n                                  minLength: 1\n                                  type: string\n                                username:\n                                  description: Username of the responder.\n                                  type: string\n                              required:\n                              - type\n                              type: object\n                            type: array\n                          sendResolved:\n                            description: Whether or not to notify about resolved alerts.\n                            type: boolean\n                          source:\n                            description: Backlink to the sender of the notification.\n                            type: string\n                          tags:\n                            description: Comma separated list of tags attached to the notifications.\n                            type: string\n                          updateAlerts:\n                            description: |-\n                              Whether to update message and description of the alert in OpsGenie if it already exists\n                              By default, the alert is never updated in OpsGenie, the new message only appears in activity log.\n                            type: boolean\n                        type: object\n                      type: array\n                    pagerdutyConfigs:\n                      description: List of PagerDuty configurations.\n                      items:\n                        description: |-\n                          PagerDutyConfig configures notifications via PagerDuty.\n                          See https://prometheus.io/docs/alerting/latest/configuration/#pagerduty_config\n                        properties:\n                          class:\n                            description: The class/type of the event.\n                            type: string\n                          client:\n                            description: Client identification.\n                            type: string\n                          clientURL:\n                            description: Backlink to the sender of notification.\n                            type: string\n                          component:\n                            description: The part or component of the affected system that is broken.\n                            type: string\n                          description:\n                            description: Description of the incident.\n                            type: string\n                          details:\n                            description: Arbitrary key/value pairs that provide further detail about the incident.\n                            items:\n                              description: KeyValue defines a (key, value) tuple.\n                              properties:\n                                key:\n                                  description: Key of the tuple.\n                                  minLength: 1\n                                  type: string\n                                value:\n                                  description: Value of the tuple.\n                                  type: string\n                              required:\n                              - key\n                              - value\n                              type: object\n                            type: array\n                          group:\n                            description: A cluster or grouping of sources.\n                            type: string\n                          httpConfig:\n                            description: HTTP client configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          pagerDutyImageConfigs:\n                            description: A list of image details to attach that provide further detail about an incident.\n                            items:\n                              description: PagerDutyImageConfig attaches images to an incident\n                              properties:\n                                alt:\n                                  description: Alt is the optional alternative text for the image.\n                                  type: string\n                                href:\n                                  description: Optional URL; makes the image a clickable link.\n                                  type: string\n                                src:\n                                  description: Src of the image being attached to the incident\n                                  type: string\n                              type: object\n                            type: array\n                          pagerDutyLinkConfigs:\n                            description: A list of link details to attach that provide further detail about an incident.\n                            items:\n                              description: PagerDutyLinkConfig attaches text links to an incident\n                              properties:\n                                alt:\n                                  description: Text that describes the purpose of the link, and can be used as the link's text.\n                                  type: string\n                                href:\n                                  description: Href is the URL of the link to be attached\n                                  type: string\n                              type: object\n                            type: array\n                          routingKey:\n                            description: |-\n                              The secret's key that contains the PagerDuty integration key (when using\n                              Events API v2). Either this field or `serviceKey` needs to be defined.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          sendResolved:\n                            description: Whether or not to notify about resolved alerts.\n                            type: boolean\n                          serviceKey:\n                            description: |-\n                              The secret's key that contains the PagerDuty service key (when using\n                              integration type \"Prometheus\"). Either this field or `routingKey` needs to\n                              be defined.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          severity:\n                            description: Severity of the incident.\n                            type: string\n                          source:\n                            description: Unique location of the affected system.\n                            type: string\n                          url:\n                            description: The URL to send requests to.\n                            type: string\n                        type: object\n                      type: array\n                    pushoverConfigs:\n                      description: List of Pushover configurations.\n                      items:\n                        description: |-\n                          PushoverConfig configures notifications via Pushover.\n                          See https://prometheus.io/docs/alerting/latest/configuration/#pushover_config\n                        properties:\n                          device:\n                            description: The name of a device to send the notification to\n                            type: string\n                          expire:\n                            description: |-\n                              How long your notification will continue to be retried for, unless the user\n                              acknowledges the notification.\n                            pattern: ^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$\n                            type: string\n                          html:\n                            description: Whether notification message is HTML or plain text.\n                            type: boolean\n                          httpConfig:\n                            description: HTTP client configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          message:\n                            description: Notification message.\n                            type: string\n                          priority:\n                            description: Priority, see https://pushover.net/api#priority\n                            type: string\n                          retry:\n                            description: |-\n                              How often the Pushover servers will send the same notification to the user.\n                              Must be at least 30 seconds.\n                            pattern: ^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$\n                            type: string\n                          sendResolved:\n                            description: Whether or not to notify about resolved alerts.\n                            type: boolean\n                          sound:\n                            description: The name of one of the sounds supported by device clients to override the user's default sound choice\n                            type: string\n                          title:\n                            description: Notification title.\n                            type: string\n                          token:\n                            description: |-\n                              The secret's key that contains the registered application's API token, see https://pushover.net/apps.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n                              Either `token` or `tokenFile` is required.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          tokenFile:\n                            description: |-\n                              The token file that contains the registered application's API token, see https://pushover.net/apps.\n                              Either `token` or `tokenFile` is required.\n                              It requires Alertmanager >= v0.26.0.\n                            type: string\n                          ttl:\n                            description: The time to live definition for the alert notification\n                            pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                            type: string\n                          url:\n                            description: A supplementary URL shown alongside the message.\n                            type: string\n                          urlTitle:\n                            description: A title for supplementary URL, otherwise just the URL is shown\n                            type: string\n                          userKey:\n                            description: |-\n                              The secret's key that contains the recipient user's user key.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n                              Either `userKey` or `userKeyFile` is required.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          userKeyFile:\n                            description: |-\n                              The user key file that contains the recipient user's user key.\n                              Either `userKey` or `userKeyFile` is required.\n                              It requires Alertmanager >= v0.26.0.\n                            type: string\n                        type: object\n                      type: array\n                    rocketchatConfigs:\n                      description: |-\n                        List of RocketChat configurations.\n                        It requires Alertmanager >= 0.28.0.\n                      items:\n                        description: |-\n                          RocketChatConfig configures notifications via RocketChat.\n                          It requires Alertmanager >= 0.28.0.\n                        properties:\n                          actions:\n                            description: Actions to include in the message.\n                            items:\n                              description: RocketChatActionConfig defines actions for RocketChat messages.\n                              properties:\n                                msg:\n                                  description: The message to send when the button is clicked.\n                                  minLength: 1\n                                  type: string\n                                text:\n                                  description: The button text.\n                                  minLength: 1\n                                  type: string\n                                url:\n                                  description: The URL the button links to.\n                                  pattern: ^https?://.+$\n                                  type: string\n                              type: object\n                            minItems: 1\n                            type: array\n                          apiURL:\n                            description: |-\n                              The API URL for RocketChat.\n                              Defaults to https://open.rocket.chat/ if not specified.\n                            pattern: ^https?://.+$\n                            type: string\n                          channel:\n                            description: The channel to send alerts to.\n                            minLength: 1\n                            type: string\n                          color:\n                            description: The message color.\n                            minLength: 1\n                            type: string\n                          emoji:\n                            description: If provided, the avatar will be displayed as an emoji.\n                            minLength: 1\n                            type: string\n                          fields:\n                            description: Additional fields for the message.\n                            items:\n                              description: RocketChatFieldConfig defines additional fields for RocketChat messages.\n                              properties:\n                                short:\n                                  description: Whether this field should be a short field.\n                                  type: boolean\n                                title:\n                                  description: The title of this field.\n                                  minLength: 1\n                                  type: string\n                                value:\n                                  description: The value of this field, displayed underneath the title value.\n                                  minLength: 1\n                                  type: string\n                              type: object\n                            minItems: 1\n                            type: array\n                          httpConfig:\n                            description: HTTP client configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          iconURL:\n                            description: Icon URL for the message.\n                            pattern: ^https?://.+$\n                            type: string\n                          imageURL:\n                            description: Image URL for the message.\n                            pattern: ^https?://.+$\n                            type: string\n                          linkNames:\n                            description: Whether to enable link names.\n                            type: boolean\n                          sendResolved:\n                            description: Whether to notify about resolved alerts.\n                            type: boolean\n                          shortFields:\n                            description: Whether to use short fields.\n                            type: boolean\n                          text:\n                            description: The message text to send, it is optional because of attachments.\n                            minLength: 1\n                            type: string\n                          thumbURL:\n                            description: Thumbnail URL for the message.\n                            pattern: ^https?://.+$\n                            type: string\n                          title:\n                            description: The message title.\n                            minLength: 1\n                            type: string\n                          titleLink:\n                            description: The title link for the message.\n                            minLength: 1\n                            type: string\n                          token:\n                            description: The sender token.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          tokenID:\n                            description: The sender token ID.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        required:\n                        - token\n                        - tokenID\n                        type: object\n                      type: array\n                    slackConfigs:\n                      description: List of Slack configurations.\n                      items:\n                        description: |-\n                          SlackConfig configures notifications via Slack.\n                          See https://prometheus.io/docs/alerting/latest/configuration/#slack_config\n                        properties:\n                          actions:\n                            description: A list of Slack actions that are sent with each notification.\n                            items:\n                              description: |-\n                                SlackAction configures a single Slack action that is sent with each\n                                notification.\n                                See https://api.slack.com/docs/message-attachments#action_fields and\n                                https://api.slack.com/docs/message-buttons for more information.\n                              properties:\n                                confirm:\n                                  description: |-\n                                    SlackConfirmationField protect users from destructive actions or\n                                    particularly distinguished decisions by asking them to confirm their button\n                                    click one more time.\n                                    See https://api.slack.com/docs/interactive-message-field-guide#confirmation_fields\n                                    for more information.\n                                  properties:\n                                    dismissText:\n                                      type: string\n                                    okText:\n                                      type: string\n                                    text:\n                                      minLength: 1\n                                      type: string\n                                    title:\n                                      type: string\n                                  required:\n                                  - text\n                                  type: object\n                                name:\n                                  type: string\n                                style:\n                                  type: string\n                                text:\n                                  minLength: 1\n                                  type: string\n                                type:\n                                  minLength: 1\n                                  type: string\n                                url:\n                                  type: string\n                                value:\n                                  type: string\n                              required:\n                              - text\n                              - type\n                              type: object\n                            type: array\n                          apiURL:\n                            description: |-\n                              The secret's key that contains the Slack webhook URL.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          callbackId:\n                            type: string\n                          channel:\n                            description: The channel or user to send notifications to.\n                            type: string\n                          color:\n                            type: string\n                          fallback:\n                            type: string\n                          fields:\n                            description: A list of Slack fields that are sent with each notification.\n                            items:\n                              description: |-\n                                SlackField configures a single Slack field that is sent with each notification.\n                                Each field must contain a title, value, and optionally, a boolean value to indicate if the field\n                                is short enough to be displayed next to other fields designated as short.\n                                See https://api.slack.com/docs/message-attachments#fields for more information.\n                              properties:\n                                short:\n                                  type: boolean\n                                title:\n                                  minLength: 1\n                                  type: string\n                                value:\n                                  minLength: 1\n                                  type: string\n                              required:\n                              - title\n                              - value\n                              type: object\n                            type: array\n                          footer:\n                            type: string\n                          httpConfig:\n                            description: HTTP client configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          iconEmoji:\n                            type: string\n                          iconURL:\n                            type: string\n                          imageURL:\n                            type: string\n                          linkNames:\n                            type: boolean\n                          mrkdwnIn:\n                            items:\n                              type: string\n                            type: array\n                          pretext:\n                            type: string\n                          sendResolved:\n                            description: Whether or not to notify about resolved alerts.\n                            type: boolean\n                          shortFields:\n                            type: boolean\n                          text:\n                            type: string\n                          thumbURL:\n                            type: string\n                          title:\n                            type: string\n                          titleLink:\n                            type: string\n                          username:\n                            type: string\n                        type: object\n                      type: array\n                    snsConfigs:\n                      description: List of SNS configurations\n                      items:\n                        description: |-\n                          SNSConfig configures notifications via AWS SNS.\n                          See https://prometheus.io/docs/alerting/latest/configuration/#sns_configs\n                        properties:\n                          apiURL:\n                            description: |-\n                              The SNS API URL i.e. https://sns.us-east-2.amazonaws.com.\n                              If not specified, the SNS API URL from the SNS SDK will be used.\n                            type: string\n                          attributes:\n                            additionalProperties:\n                              type: string\n                            description: SNS message attributes.\n                            type: object\n                          httpConfig:\n                            description: HTTP client configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          message:\n                            description: The message content of the SNS notification.\n                            type: string\n                          phoneNumber:\n                            description: |-\n                              Phone number if message is delivered via SMS in E.164 format.\n                              If you don't specify this value, you must specify a value for the TopicARN or TargetARN.\n                            type: string\n                          sendResolved:\n                            description: Whether or not to notify about resolved alerts.\n                            type: boolean\n                          sigv4:\n                            description: Configures AWS's Signature Verification 4 signing process to sign requests.\n                            properties:\n                              accessKey:\n                                description: |-\n                                  AccessKey is the AWS API key. If not specified, the environment variable\n                                  `AWS_ACCESS_KEY_ID` is used.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              profile:\n                                description: Profile is the named AWS profile used to authenticate.\n                                type: string\n                              region:\n                                description: Region is the AWS region. If blank, the region from the default credentials chain used.\n                                type: string\n                              roleArn:\n                                description: RoleArn is the named AWS profile used to authenticate.\n                                type: string\n                              secretKey:\n                                description: |-\n                                  SecretKey is the AWS API secret. If not specified, the environment\n                                  variable `AWS_SECRET_ACCESS_KEY` is used.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            type: object\n                          subject:\n                            description: Subject line when the message is delivered to email endpoints.\n                            type: string\n                          targetARN:\n                            description: |-\n                              The  mobile platform endpoint ARN if message is delivered via mobile notifications.\n                              If you don't specify this value, you must specify a value for the topic_arn or PhoneNumber.\n                            type: string\n                          topicARN:\n                            description: |-\n                              SNS topic ARN, i.e. arn:aws:sns:us-east-2:698519295917:My-Topic\n                              If you don't specify this value, you must specify a value for the PhoneNumber or TargetARN.\n                            type: string\n                        type: object\n                      type: array\n                    telegramConfigs:\n                      description: List of Telegram configurations.\n                      items:\n                        description: |-\n                          TelegramConfig configures notifications via Telegram.\n                          See https://prometheus.io/docs/alerting/latest/configuration/#telegram_config\n                        properties:\n                          apiURL:\n                            description: |-\n                              The Telegram API URL i.e. https://api.telegram.org.\n                              If not specified, default API URL will be used.\n                            type: string\n                          botToken:\n                            description: |-\n                              Telegram bot token. It is mutually exclusive with `botTokenFile`.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n\n                              Either `botToken` or `botTokenFile` is required.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          botTokenFile:\n                            description: |-\n                              File to read the Telegram bot token from. It is mutually exclusive with `botToken`.\n                              Either `botToken` or `botTokenFile` is required.\n\n                              It requires Alertmanager >= v0.26.0.\n                            type: string\n                          chatID:\n                            description: The Telegram chat ID.\n                            format: int64\n                            type: integer\n                          disableNotifications:\n                            description: Disable telegram notifications\n                            type: boolean\n                          httpConfig:\n                            description: HTTP client configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          message:\n                            description: Message template\n                            type: string\n                          messageThreadID:\n                            description: |-\n                              The Telegram Group Topic ID.\n                              It requires Alertmanager >= 0.26.0.\n                            format: int64\n                            type: integer\n                          parseMode:\n                            description: Parse mode for telegram message\n                            enum:\n                            - MarkdownV2\n                            - Markdown\n                            - HTML\n                            type: string\n                          sendResolved:\n                            description: Whether to notify about resolved alerts.\n                            type: boolean\n                        required:\n                        - chatID\n                        type: object\n                      type: array\n                    victoropsConfigs:\n                      description: List of VictorOps configurations.\n                      items:\n                        description: |-\n                          VictorOpsConfig configures notifications via VictorOps.\n                          See https://prometheus.io/docs/alerting/latest/configuration/#victorops_config\n                        properties:\n                          apiKey:\n                            description: |-\n                              The secret's key that contains the API key to use when talking to the VictorOps API.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          apiUrl:\n                            description: The VictorOps API URL.\n                            type: string\n                          customFields:\n                            description: Additional custom fields for notification.\n                            items:\n                              description: KeyValue defines a (key, value) tuple.\n                              properties:\n                                key:\n                                  description: Key of the tuple.\n                                  minLength: 1\n                                  type: string\n                                value:\n                                  description: Value of the tuple.\n                                  type: string\n                              required:\n                              - key\n                              - value\n                              type: object\n                            type: array\n                          entityDisplayName:\n                            description: Contains summary of the alerted problem.\n                            type: string\n                          httpConfig:\n                            description: The HTTP client's configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          messageType:\n                            description: Describes the behavior of the alert (CRITICAL, WARNING, INFO).\n                            type: string\n                          monitoringTool:\n                            description: The monitoring tool the state message is from.\n                            type: string\n                          routingKey:\n                            description: A key used to map the alert to a team.\n                            type: string\n                          sendResolved:\n                            description: Whether or not to notify about resolved alerts.\n                            type: boolean\n                          stateMessage:\n                            description: Contains long explanation of the alerted problem.\n                            type: string\n                        type: object\n                      type: array\n                    webexConfigs:\n                      description: List of Webex configurations.\n                      items:\n                        description: |-\n                          WebexConfig configures notification via Cisco Webex\n                          See https://prometheus.io/docs/alerting/latest/configuration/#webex_config\n                        properties:\n                          apiURL:\n                            description: |-\n                              The Webex Teams API URL i.e. https://webexapis.com/v1/messages\n                              Provide if different from the default API URL.\n                            pattern: ^https?://.+$\n                            type: string\n                          httpConfig:\n                            description: |-\n                              The HTTP client's configuration.\n                              You must supply the bot token via the `httpConfig.authorization` field.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          message:\n                            description: Message template\n                            type: string\n                          roomID:\n                            description: ID of the Webex Teams room where to send the messages.\n                            minLength: 1\n                            type: string\n                          sendResolved:\n                            description: Whether to notify about resolved alerts.\n                            type: boolean\n                        required:\n                        - roomID\n                        type: object\n                      type: array\n                    webhookConfigs:\n                      description: List of webhook configurations.\n                      items:\n                        description: |-\n                          WebhookConfig configures notifications via a generic receiver supporting the webhook payload.\n                          See https://prometheus.io/docs/alerting/latest/configuration/#webhook_config\n                        properties:\n                          httpConfig:\n                            description: HTTP client configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          maxAlerts:\n                            description: Maximum number of alerts to be sent per webhook message. When 0, all alerts are included.\n                            format: int32\n                            minimum: 0\n                            type: integer\n                          sendResolved:\n                            description: Whether or not to notify about resolved alerts.\n                            type: boolean\n                          timeout:\n                            description: |-\n                              The maximum time to wait for a webhook request to complete, before failing the\n                              request and allowing it to be retried.\n                              It requires Alertmanager >= v0.28.0.\n                            pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                            type: string\n                          url:\n                            description: |-\n                              The URL to send HTTP POST requests to. `urlSecret` takes precedence over\n                              `url`. One of `urlSecret` and `url` should be defined.\n                            type: string\n                          urlSecret:\n                            description: |-\n                              The secret's key that contains the webhook URL to send HTTP requests to.\n                              `urlSecret` takes precedence over `url`. One of `urlSecret` and `url`\n                              should be defined.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      type: array\n                    wechatConfigs:\n                      description: List of WeChat configurations.\n                      items:\n                        description: |-\n                          WeChatConfig configures notifications via WeChat.\n                          See https://prometheus.io/docs/alerting/latest/configuration/#wechat_config\n                        properties:\n                          agentID:\n                            type: string\n                          apiSecret:\n                            description: |-\n                              The secret's key that contains the WeChat API key.\n                              The secret needs to be in the same namespace as the AlertmanagerConfig\n                              object and accessible by the Prometheus Operator.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          apiURL:\n                            description: The WeChat API URL.\n                            type: string\n                          corpID:\n                            description: The corp id for authentication.\n                            type: string\n                          httpConfig:\n                            description: HTTP client configuration.\n                            properties:\n                              authorization:\n                                description: |-\n                                  Authorization header configuration for the client.\n                                  This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                                properties:\n                                  credentials:\n                                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type:\n                                    description: |-\n                                      Defines the authentication type. The value is case-insensitive.\n\n                                      \"Basic\" is not a supported value.\n\n                                      Default: \"Bearer\"\n                                    type: string\n                                type: object\n                              basicAuth:\n                                description: |-\n                                  BasicAuth for the client.\n                                  This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                                properties:\n                                  password:\n                                    description: |-\n                                      `password` specifies a key of a Secret containing the password for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  username:\n                                    description: |-\n                                      `username` specifies a key of a Secret containing the username for\n                                      authentication.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              bearerTokenSecret:\n                                description: |-\n                                  The secret's key that contains the bearer token to be used by the client\n                                  for authentication.\n                                  The secret needs to be in the same namespace as the AlertmanagerConfig\n                                  object and accessible by the Prometheus Operator.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              followRedirects:\n                                description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                                type: boolean\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              oauth2:\n                                description: OAuth2 client credentials used to fetch a token for the targets.\n                                properties:\n                                  clientId:\n                                    description: |-\n                                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                                      OAuth2 client's ID.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  clientSecret:\n                                    description: |-\n                                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                                      client's secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  endpointParams:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      `endpointParams` configures the HTTP parameters to append to the token\n                                      URL.\n                                    type: object\n                                  noProxy:\n                                    description: |-\n                                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                      that should be excluded from proxying. IP and domain names can\n                                      contain port numbers.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: string\n                                  proxyConnectHeader:\n                                    additionalProperties:\n                                      items:\n                                        description: SecretKeySelector selects a key of a Secret.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      type: array\n                                    description: |-\n                                      ProxyConnectHeader optionally specifies headers to send to\n                                      proxies during CONNECT requests.\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  proxyFromEnvironment:\n                                    description: |-\n                                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                    type: boolean\n                                  proxyUrl:\n                                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                                    pattern: ^(http|https|socks5)://.+$\n                                    type: string\n                                  scopes:\n                                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                    items:\n                                      type: string\n                                    type: array\n                                  tlsConfig:\n                                    description: |-\n                                      TLS configuration to use when connecting to the OAuth2 server.\n                                      It requires Prometheus >= v2.43.0.\n                                    properties:\n                                      ca:\n                                        description: Certificate authority used when verifying server certificates.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      cert:\n                                        description: Client certificate to present when doing client-authentication.\n                                        properties:\n                                          configMap:\n                                            description: ConfigMap containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key to select.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the ConfigMap or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                          secret:\n                                            description: Secret containing data to use for the targets.\n                                            properties:\n                                              key:\n                                                description: The key of the secret to select from.  Must be a valid secret key.\n                                                type: string\n                                              name:\n                                                default: \"\"\n                                                description: |-\n                                                  Name of the referent.\n                                                  This field is effectively required, but due to backwards compatibility is\n                                                  allowed to be empty. Instances of this type with an empty value here are\n                                                  almost certainly wrong.\n                                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                                type: string\n                                              optional:\n                                                description: Specify whether the Secret or its key must be defined\n                                                type: boolean\n                                            required:\n                                            - key\n                                            type: object\n                                            x-kubernetes-map-type: atomic\n                                        type: object\n                                      insecureSkipVerify:\n                                        description: Disable target certificate validation.\n                                        type: boolean\n                                      keySecret:\n                                        description: Secret containing the client key file for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      maxVersion:\n                                        description: |-\n                                          Maximum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      minVersion:\n                                        description: |-\n                                          Minimum acceptable TLS version.\n\n                                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                        enum:\n                                        - TLS10\n                                        - TLS11\n                                        - TLS12\n                                        - TLS13\n                                        type: string\n                                      serverName:\n                                        description: Used to verify the hostname for the targets.\n                                        type: string\n                                    type: object\n                                  tokenUrl:\n                                    description: '`tokenURL` configures the URL to fetch the token from.'\n                                    minLength: 1\n                                    type: string\n                                required:\n                                - clientId\n                                - clientSecret\n                                - tokenUrl\n                                type: object\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyURL:\n                                description: |-\n                                  Optional proxy URL.\n\n                                  If defined, this field takes precedence over `proxyUrl`.\n                                type: string\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              tlsConfig:\n                                description: TLS configuration for the client.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                            type: object\n                          message:\n                            description: API request data as defined by the WeChat API.\n                            type: string\n                          messageType:\n                            type: string\n                          sendResolved:\n                            description: Whether or not to notify about resolved alerts.\n                            type: boolean\n                          toParty:\n                            type: string\n                          toTag:\n                            type: string\n                          toUser:\n                            type: string\n                        type: object\n                      type: array\n                  required:\n                  - name\n                  type: object\n                type: array\n              route:\n                description: |-\n                  The Alertmanager route definition for alerts matching the resource's\n                  namespace. If present, it will be added to the generated Alertmanager\n                  configuration as a first-level route.\n                properties:\n                  activeTimeIntervals:\n                    description: ActiveTimeIntervals is a list of MuteTimeInterval names when this route should be active.\n                    items:\n                      type: string\n                    type: array\n                  continue:\n                    description: |-\n                      Boolean indicating whether an alert should continue matching subsequent\n                      sibling nodes. It will always be overridden to true for the first-level\n                      route by the Prometheus operator.\n                    type: boolean\n                  groupBy:\n                    description: |-\n                      List of labels to group by.\n                      Labels must not be repeated (unique list).\n                      Special label \"...\" (aggregate by all possible labels), if provided, must be the only element in the list.\n                    items:\n                      type: string\n                    type: array\n                  groupInterval:\n                    description: |-\n                      How long to wait before sending an updated notification.\n                      Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$`\n                      Example: \"5m\"\n                    type: string\n                  groupWait:\n                    description: |-\n                      How long to wait before sending the initial notification.\n                      Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$`\n                      Example: \"30s\"\n                    type: string\n                  matchers:\n                    description: |-\n                      List of matchers that the alert's labels should match. For the first\n                      level route, the operator removes any existing equality and regexp\n                      matcher on the `namespace` label and adds a `namespace: <object\n                      namespace>` matcher.\n                    items:\n                      description: Matcher defines how to match on alert's labels.\n                      properties:\n                        matchType:\n                          description: |-\n                            Match operation available with AlertManager >= v0.22.0 and\n                            takes precedence over Regex (deprecated) if non-empty.\n                          enum:\n                          - '!='\n                          - =\n                          - =~\n                          - '!~'\n                          type: string\n                        name:\n                          description: Label to match.\n                          minLength: 1\n                          type: string\n                        regex:\n                          description: |-\n                            Whether to match on equality (false) or regular-expression (true).\n                            Deprecated: for AlertManager >= v0.22.0, `matchType` should be used instead.\n                          type: boolean\n                        value:\n                          description: Label value to match.\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    type: array\n                  muteTimeIntervals:\n                    description: |-\n                      Note: this comment applies to the field definition above but appears\n                      below otherwise it gets included in the generated manifest.\n                      CRD schema doesn't support self-referential types for now (see\n                      https://github.com/kubernetes/kubernetes/issues/62872). We have to use\n                      an alternative type to circumvent the limitation. The downside is that\n                      the Kube API can't validate the data beyond the fact that it is a valid\n                      JSON representation.\n                      MuteTimeIntervals is a list of MuteTimeInterval names that will mute this route when matched,\n                    items:\n                      type: string\n                    type: array\n                  receiver:\n                    description: |-\n                      Name of the receiver for this route. If not empty, it should be listed in\n                      the `receivers` field.\n                    type: string\n                  repeatInterval:\n                    description: |-\n                      How long to wait before repeating the last notification.\n                      Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$`\n                      Example: \"4h\"\n                    type: string\n                  routes:\n                    description: Child routes.\n                    items:\n                      x-kubernetes-preserve-unknown-fields: true\n                    type: array\n                type: object\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n"
  },
  {
    "path": "hack/config/monitoring/crds/0alertmanagerCustomResourceDefinition.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.18.0\n    operator.prometheus.io/version: 0.85.0\n  name: alertmanagers.monitoring.coreos.com\nspec:\n  group: monitoring.coreos.com\n  names:\n    categories:\n    - prometheus-operator\n    kind: Alertmanager\n    listKind: AlertmanagerList\n    plural: alertmanagers\n    shortNames:\n    - am\n    singular: alertmanager\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - description: The version of Alertmanager\n      jsonPath: .spec.version\n      name: Version\n      type: string\n    - description: The number of desired replicas\n      jsonPath: .spec.replicas\n      name: Replicas\n      type: integer\n    - description: The number of ready replicas\n      jsonPath: .status.availableReplicas\n      name: Ready\n      type: integer\n    - jsonPath: .status.conditions[?(@.type == 'Reconciled')].status\n      name: Reconciled\n      type: string\n    - jsonPath: .status.conditions[?(@.type == 'Available')].status\n      name: Available\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    - description: Whether the resource reconciliation is paused or not\n      jsonPath: .status.paused\n      name: Paused\n      priority: 1\n      type: boolean\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The `Alertmanager` custom resource definition (CRD) defines a desired [Alertmanager](https://prometheus.io/docs/alerting) setup to run in a Kubernetes cluster. It allows to specify many options such as the number of replicas, persistent storage and many more.\n\n          For each `Alertmanager` resource, the Operator deploys a `StatefulSet` in the same namespace. When there are two or more configured replicas, the Operator runs the Alertmanager instances in high-availability mode.\n\n          The resource defines via label and namespace selectors which `AlertmanagerConfig` objects should be associated to the deployed Alertmanager instances.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: |-\n              Specification of the desired behavior of the Alertmanager cluster. More info:\n              https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n            properties:\n              additionalArgs:\n                description: |-\n                  AdditionalArgs allows setting additional arguments for the 'Alertmanager' container.\n                  It is intended for e.g. activating hidden flags which are not supported by\n                  the dedicated configuration options yet. The arguments are passed as-is to the\n                  Alertmanager container which may cause issues if they are invalid or not supported\n                  by the given Alertmanager version.\n                items:\n                  description: Argument as part of the AdditionalArgs list.\n                  properties:\n                    name:\n                      description: Name of the argument, e.g. \"scrape.discovery-reload-interval\".\n                      minLength: 1\n                      type: string\n                    value:\n                      description: Argument value, e.g. 30s. Can be empty for name-only arguments (e.g. --storage.tsdb.no-lockfile)\n                      type: string\n                  required:\n                  - name\n                  type: object\n                type: array\n              additionalPeers:\n                description: AdditionalPeers allows injecting a set of additional Alertmanagers to peer with to form a highly available cluster.\n                items:\n                  type: string\n                type: array\n              affinity:\n                description: If specified, the pod's scheduling constraints.\n                properties:\n                  nodeAffinity:\n                    description: Describes node affinity scheduling rules for the pod.\n                    properties:\n                      preferredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          The scheduler will prefer to schedule pods to nodes that satisfy\n                          the affinity expressions specified by this field, but it may choose\n                          a node that violates one or more of the expressions. The node that is\n                          most preferred is the one with the greatest sum of weights, i.e.\n                          for each node that meets all of the scheduling requirements (resource\n                          request, requiredDuringScheduling affinity expressions, etc.),\n                          compute a sum by iterating through the elements of this field and adding\n                          \"weight\" to the sum if the node matches the corresponding matchExpressions; the\n                          node(s) with the highest sum are the most preferred.\n                        items:\n                          description: |-\n                            An empty preferred scheduling term matches all objects with implicit weight 0\n                            (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).\n                          properties:\n                            preference:\n                              description: A node selector term, associated with the corresponding weight.\n                              properties:\n                                matchExpressions:\n                                  description: A list of node selector requirements by node's labels.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchFields:\n                                  description: A list of node selector requirements by node's fields.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            weight:\n                              description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.\n                              format: int32\n                              type: integer\n                          required:\n                          - preference\n                          - weight\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                      requiredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          If the affinity requirements specified by this field are not met at\n                          scheduling time, the pod will not be scheduled onto the node.\n                          If the affinity requirements specified by this field cease to be met\n                          at some point during pod execution (e.g. due to an update), the system\n                          may or may not try to eventually evict the pod from its node.\n                        properties:\n                          nodeSelectorTerms:\n                            description: Required. A list of node selector terms. The terms are ORed.\n                            items:\n                              description: |-\n                                A null or empty node selector term matches no objects. The requirements of\n                                them are ANDed.\n                                The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.\n                              properties:\n                                matchExpressions:\n                                  description: A list of node selector requirements by node's labels.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchFields:\n                                  description: A list of node selector requirements by node's fields.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                            x-kubernetes-list-type: atomic\n                        required:\n                        - nodeSelectorTerms\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  podAffinity:\n                    description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)).\n                    properties:\n                      preferredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          The scheduler will prefer to schedule pods to nodes that satisfy\n                          the affinity expressions specified by this field, but it may choose\n                          a node that violates one or more of the expressions. The node that is\n                          most preferred is the one with the greatest sum of weights, i.e.\n                          for each node that meets all of the scheduling requirements (resource\n                          request, requiredDuringScheduling affinity expressions, etc.),\n                          compute a sum by iterating through the elements of this field and adding\n                          \"weight\" to the sum if the node has pods which matches the corresponding podAffinityTerm; the\n                          node(s) with the highest sum are the most preferred.\n                        items:\n                          description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)\n                          properties:\n                            podAffinityTerm:\n                              description: Required. A pod affinity term, associated with the corresponding weight.\n                              properties:\n                                labelSelector:\n                                  description: |-\n                                    A label query over a set of resources, in this case pods.\n                                    If it's null, this PodAffinityTerm matches with no Pods.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                matchLabelKeys:\n                                  description: |-\n                                    MatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                    Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                mismatchLabelKeys:\n                                  description: |-\n                                    MismatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                    Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                namespaceSelector:\n                                  description: |-\n                                    A label query over the set of namespaces that the term applies to.\n                                    The term is applied to the union of the namespaces selected by this field\n                                    and the ones listed in the namespaces field.\n                                    null selector and null or empty namespaces list means \"this pod's namespace\".\n                                    An empty selector ({}) matches all namespaces.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                namespaces:\n                                  description: |-\n                                    namespaces specifies a static list of namespace names that the term applies to.\n                                    The term is applied to the union of the namespaces listed in this field\n                                    and the ones selected by namespaceSelector.\n                                    null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                topologyKey:\n                                  description: |-\n                                    This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                    the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                    whose value of the label with key topologyKey matches that of any node on which any of the\n                                    selected pods is running.\n                                    Empty topologyKey is not allowed.\n                                  type: string\n                              required:\n                              - topologyKey\n                              type: object\n                            weight:\n                              description: |-\n                                weight associated with matching the corresponding podAffinityTerm,\n                                in the range 1-100.\n                              format: int32\n                              type: integer\n                          required:\n                          - podAffinityTerm\n                          - weight\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                      requiredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          If the affinity requirements specified by this field are not met at\n                          scheduling time, the pod will not be scheduled onto the node.\n                          If the affinity requirements specified by this field cease to be met\n                          at some point during pod execution (e.g. due to a pod label update), the\n                          system may or may not try to eventually evict the pod from its node.\n                          When there are multiple elements, the lists of nodes corresponding to each\n                          podAffinityTerm are intersected, i.e. all terms must be satisfied.\n                        items:\n                          description: |-\n                            Defines a set of pods (namely those matching the labelSelector\n                            relative to the given namespace(s)) that this pod should be\n                            co-located (affinity) or not co-located (anti-affinity) with,\n                            where co-located is defined as running on a node whose value of\n                            the label with key <topologyKey> matches that of any node on which\n                            a pod of the set of pods is running\n                          properties:\n                            labelSelector:\n                              description: |-\n                                A label query over a set of resources, in this case pods.\n                                If it's null, this PodAffinityTerm matches with no Pods.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            matchLabelKeys:\n                              description: |-\n                                MatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            mismatchLabelKeys:\n                              description: |-\n                                MismatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            namespaceSelector:\n                              description: |-\n                                A label query over the set of namespaces that the term applies to.\n                                The term is applied to the union of the namespaces selected by this field\n                                and the ones listed in the namespaces field.\n                                null selector and null or empty namespaces list means \"this pod's namespace\".\n                                An empty selector ({}) matches all namespaces.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            namespaces:\n                              description: |-\n                                namespaces specifies a static list of namespace names that the term applies to.\n                                The term is applied to the union of the namespaces listed in this field\n                                and the ones selected by namespaceSelector.\n                                null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            topologyKey:\n                              description: |-\n                                This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                whose value of the label with key topologyKey matches that of any node on which any of the\n                                selected pods is running.\n                                Empty topologyKey is not allowed.\n                              type: string\n                          required:\n                          - topologyKey\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                    type: object\n                  podAntiAffinity:\n                    description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).\n                    properties:\n                      preferredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          The scheduler will prefer to schedule pods to nodes that satisfy\n                          the anti-affinity expressions specified by this field, but it may choose\n                          a node that violates one or more of the expressions. The node that is\n                          most preferred is the one with the greatest sum of weights, i.e.\n                          for each node that meets all of the scheduling requirements (resource\n                          request, requiredDuringScheduling anti-affinity expressions, etc.),\n                          compute a sum by iterating through the elements of this field and adding\n                          \"weight\" to the sum if the node has pods which matches the corresponding podAffinityTerm; the\n                          node(s) with the highest sum are the most preferred.\n                        items:\n                          description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)\n                          properties:\n                            podAffinityTerm:\n                              description: Required. A pod affinity term, associated with the corresponding weight.\n                              properties:\n                                labelSelector:\n                                  description: |-\n                                    A label query over a set of resources, in this case pods.\n                                    If it's null, this PodAffinityTerm matches with no Pods.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                matchLabelKeys:\n                                  description: |-\n                                    MatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                    Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                mismatchLabelKeys:\n                                  description: |-\n                                    MismatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                    Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                namespaceSelector:\n                                  description: |-\n                                    A label query over the set of namespaces that the term applies to.\n                                    The term is applied to the union of the namespaces selected by this field\n                                    and the ones listed in the namespaces field.\n                                    null selector and null or empty namespaces list means \"this pod's namespace\".\n                                    An empty selector ({}) matches all namespaces.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                namespaces:\n                                  description: |-\n                                    namespaces specifies a static list of namespace names that the term applies to.\n                                    The term is applied to the union of the namespaces listed in this field\n                                    and the ones selected by namespaceSelector.\n                                    null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                topologyKey:\n                                  description: |-\n                                    This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                    the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                    whose value of the label with key topologyKey matches that of any node on which any of the\n                                    selected pods is running.\n                                    Empty topologyKey is not allowed.\n                                  type: string\n                              required:\n                              - topologyKey\n                              type: object\n                            weight:\n                              description: |-\n                                weight associated with matching the corresponding podAffinityTerm,\n                                in the range 1-100.\n                              format: int32\n                              type: integer\n                          required:\n                          - podAffinityTerm\n                          - weight\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                      requiredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          If the anti-affinity requirements specified by this field are not met at\n                          scheduling time, the pod will not be scheduled onto the node.\n                          If the anti-affinity requirements specified by this field cease to be met\n                          at some point during pod execution (e.g. due to a pod label update), the\n                          system may or may not try to eventually evict the pod from its node.\n                          When there are multiple elements, the lists of nodes corresponding to each\n                          podAffinityTerm are intersected, i.e. all terms must be satisfied.\n                        items:\n                          description: |-\n                            Defines a set of pods (namely those matching the labelSelector\n                            relative to the given namespace(s)) that this pod should be\n                            co-located (affinity) or not co-located (anti-affinity) with,\n                            where co-located is defined as running on a node whose value of\n                            the label with key <topologyKey> matches that of any node on which\n                            a pod of the set of pods is running\n                          properties:\n                            labelSelector:\n                              description: |-\n                                A label query over a set of resources, in this case pods.\n                                If it's null, this PodAffinityTerm matches with no Pods.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            matchLabelKeys:\n                              description: |-\n                                MatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            mismatchLabelKeys:\n                              description: |-\n                                MismatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            namespaceSelector:\n                              description: |-\n                                A label query over the set of namespaces that the term applies to.\n                                The term is applied to the union of the namespaces selected by this field\n                                and the ones listed in the namespaces field.\n                                null selector and null or empty namespaces list means \"this pod's namespace\".\n                                An empty selector ({}) matches all namespaces.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            namespaces:\n                              description: |-\n                                namespaces specifies a static list of namespace names that the term applies to.\n                                The term is applied to the union of the namespaces listed in this field\n                                and the ones selected by namespaceSelector.\n                                null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            topologyKey:\n                              description: |-\n                                This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                whose value of the label with key topologyKey matches that of any node on which any of the\n                                selected pods is running.\n                                Empty topologyKey is not allowed.\n                              type: string\n                          required:\n                          - topologyKey\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                    type: object\n                type: object\n              alertmanagerConfigMatcherStrategy:\n                description: |-\n                  AlertmanagerConfigMatcherStrategy defines how AlertmanagerConfig objects\n                  process incoming alerts.\n                properties:\n                  type:\n                    default: OnNamespace\n                    description: |-\n                      AlertmanagerConfigMatcherStrategyType defines the strategy used by\n                      AlertmanagerConfig objects to match alerts in the routes and inhibition\n                      rules.\n\n                      The default value is `OnNamespace`.\n                    enum:\n                    - OnNamespace\n                    - OnNamespaceExceptForAlertmanagerNamespace\n                    - None\n                    type: string\n                type: object\n              alertmanagerConfigNamespaceSelector:\n                description: |-\n                  Namespaces to be selected for AlertmanagerConfig discovery. If nil, only\n                  check own namespace.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              alertmanagerConfigSelector:\n                description: AlertmanagerConfigs to be selected for to merge and configure Alertmanager with.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              alertmanagerConfiguration:\n                description: |-\n                  alertmanagerConfiguration specifies the configuration of Alertmanager.\n\n                  If defined, it takes precedence over the `configSecret` field.\n\n                  This is an *experimental feature*, it may change in any upcoming release\n                  in a breaking way.\n                properties:\n                  global:\n                    description: Defines the global parameters of the Alertmanager configuration.\n                    properties:\n                      httpConfig:\n                        description: HTTP client configuration.\n                        properties:\n                          authorization:\n                            description: |-\n                              Authorization header configuration for the client.\n                              This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+.\n                            properties:\n                              credentials:\n                                description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              type:\n                                description: |-\n                                  Defines the authentication type. The value is case-insensitive.\n\n                                  \"Basic\" is not a supported value.\n\n                                  Default: \"Bearer\"\n                                type: string\n                            type: object\n                          basicAuth:\n                            description: |-\n                              BasicAuth for the client.\n                              This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence.\n                            properties:\n                              password:\n                                description: |-\n                                  `password` specifies a key of a Secret containing the password for\n                                  authentication.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              username:\n                                description: |-\n                                  `username` specifies a key of a Secret containing the username for\n                                  authentication.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            type: object\n                          bearerTokenSecret:\n                            description: |-\n                              The secret's key that contains the bearer token to be used by the client\n                              for authentication.\n                              The secret needs to be in the same namespace as the Alertmanager\n                              object and accessible by the Prometheus Operator.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          followRedirects:\n                            description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects.\n                            type: boolean\n                          noProxy:\n                            description: |-\n                              `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                              that should be excluded from proxying. IP and domain names can\n                              contain port numbers.\n\n                              It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                            type: string\n                          oauth2:\n                            description: OAuth2 client credentials used to fetch a token for the targets.\n                            properties:\n                              clientId:\n                                description: |-\n                                  `clientId` specifies a key of a Secret or ConfigMap containing the\n                                  OAuth2 client's ID.\n                                properties:\n                                  configMap:\n                                    description: ConfigMap containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key to select.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the ConfigMap or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  secret:\n                                    description: Secret containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              clientSecret:\n                                description: |-\n                                  `clientSecret` specifies a key of a Secret containing the OAuth2\n                                  client's secret.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              endpointParams:\n                                additionalProperties:\n                                  type: string\n                                description: |-\n                                  `endpointParams` configures the HTTP parameters to append to the token\n                                  URL.\n                                type: object\n                              noProxy:\n                                description: |-\n                                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                                  that should be excluded from proxying. IP and domain names can\n                                  contain port numbers.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: string\n                              proxyConnectHeader:\n                                additionalProperties:\n                                  items:\n                                    description: SecretKeySelector selects a key of a Secret.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  type: array\n                                description: |-\n                                  ProxyConnectHeader optionally specifies headers to send to\n                                  proxies during CONNECT requests.\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              proxyFromEnvironment:\n                                description: |-\n                                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                                type: boolean\n                              proxyUrl:\n                                description: '`proxyURL` defines the HTTP proxy server to use.'\n                                pattern: ^(http|https|socks5)://.+$\n                                type: string\n                              scopes:\n                                description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                                items:\n                                  type: string\n                                type: array\n                              tlsConfig:\n                                description: |-\n                                  TLS configuration to use when connecting to the OAuth2 server.\n                                  It requires Prometheus >= v2.43.0.\n                                properties:\n                                  ca:\n                                    description: Certificate authority used when verifying server certificates.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  cert:\n                                    description: Client certificate to present when doing client-authentication.\n                                    properties:\n                                      configMap:\n                                        description: ConfigMap containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key to select.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the ConfigMap or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                      secret:\n                                        description: Secret containing data to use for the targets.\n                                        properties:\n                                          key:\n                                            description: The key of the secret to select from.  Must be a valid secret key.\n                                            type: string\n                                          name:\n                                            default: \"\"\n                                            description: |-\n                                              Name of the referent.\n                                              This field is effectively required, but due to backwards compatibility is\n                                              allowed to be empty. Instances of this type with an empty value here are\n                                              almost certainly wrong.\n                                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                            type: string\n                                          optional:\n                                            description: Specify whether the Secret or its key must be defined\n                                            type: boolean\n                                        required:\n                                        - key\n                                        type: object\n                                        x-kubernetes-map-type: atomic\n                                    type: object\n                                  insecureSkipVerify:\n                                    description: Disable target certificate validation.\n                                    type: boolean\n                                  keySecret:\n                                    description: Secret containing the client key file for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  maxVersion:\n                                    description: |-\n                                      Maximum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  minVersion:\n                                    description: |-\n                                      Minimum acceptable TLS version.\n\n                                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                    enum:\n                                    - TLS10\n                                    - TLS11\n                                    - TLS12\n                                    - TLS13\n                                    type: string\n                                  serverName:\n                                    description: Used to verify the hostname for the targets.\n                                    type: string\n                                type: object\n                              tokenUrl:\n                                description: '`tokenURL` configures the URL to fetch the token from.'\n                                minLength: 1\n                                type: string\n                            required:\n                            - clientId\n                            - clientSecret\n                            - tokenUrl\n                            type: object\n                          proxyConnectHeader:\n                            additionalProperties:\n                              items:\n                                description: SecretKeySelector selects a key of a Secret.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              type: array\n                            description: |-\n                              ProxyConnectHeader optionally specifies headers to send to\n                              proxies during CONNECT requests.\n\n                              It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          proxyFromEnvironment:\n                            description: |-\n                              Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                              It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                            type: boolean\n                          proxyUrl:\n                            description: '`proxyURL` defines the HTTP proxy server to use.'\n                            pattern: ^(http|https|socks5)://.+$\n                            type: string\n                          tlsConfig:\n                            description: TLS configuration for the client.\n                            properties:\n                              ca:\n                                description: Certificate authority used when verifying server certificates.\n                                properties:\n                                  configMap:\n                                    description: ConfigMap containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key to select.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the ConfigMap or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  secret:\n                                    description: Secret containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              cert:\n                                description: Client certificate to present when doing client-authentication.\n                                properties:\n                                  configMap:\n                                    description: ConfigMap containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key to select.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the ConfigMap or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  secret:\n                                    description: Secret containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              insecureSkipVerify:\n                                description: Disable target certificate validation.\n                                type: boolean\n                              keySecret:\n                                description: Secret containing the client key file for the targets.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              maxVersion:\n                                description: |-\n                                  Maximum acceptable TLS version.\n\n                                  It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                enum:\n                                - TLS10\n                                - TLS11\n                                - TLS12\n                                - TLS13\n                                type: string\n                              minVersion:\n                                description: |-\n                                  Minimum acceptable TLS version.\n\n                                  It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                enum:\n                                - TLS10\n                                - TLS11\n                                - TLS12\n                                - TLS13\n                                type: string\n                              serverName:\n                                description: Used to verify the hostname for the targets.\n                                type: string\n                            type: object\n                        type: object\n                      jira:\n                        description: The default configuration for Jira.\n                        properties:\n                          apiURL:\n                            description: |-\n                              The default Jira API URL.\n\n                              It requires Alertmanager >= v0.28.0.\n                            pattern: ^(http|https)://.+$\n                            type: string\n                        type: object\n                      opsGenieApiKey:\n                        description: The default OpsGenie API Key.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      opsGenieApiUrl:\n                        description: The default OpsGenie API URL.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      pagerdutyUrl:\n                        description: The default Pagerduty URL.\n                        type: string\n                      resolveTimeout:\n                        description: |-\n                          ResolveTimeout is the default value used by alertmanager if the alert does\n                          not include EndsAt, after this time passes it can declare the alert as resolved if it has not been updated.\n                          This has no impact on alerts from Prometheus, as they always include EndsAt.\n                        pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                        type: string\n                      rocketChat:\n                        description: The default configuration for Rocket Chat.\n                        properties:\n                          apiURL:\n                            description: |-\n                              The default Rocket Chat API URL.\n\n                              It requires Alertmanager >= v0.28.0.\n                            pattern: ^(http|https)://.+$\n                            type: string\n                          token:\n                            description: |-\n                              The default Rocket Chat token.\n\n                              It requires Alertmanager >= v0.28.0.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          tokenID:\n                            description: |-\n                              The default Rocket Chat Token ID.\n\n                              It requires Alertmanager >= v0.28.0.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      slackApiUrl:\n                        description: The default Slack API URL.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      smtp:\n                        description: Configures global SMTP parameters.\n                        properties:\n                          authIdentity:\n                            description: SMTP Auth using PLAIN\n                            type: string\n                          authPassword:\n                            description: SMTP Auth using LOGIN and PLAIN.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          authSecret:\n                            description: SMTP Auth using CRAM-MD5.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          authUsername:\n                            description: SMTP Auth using CRAM-MD5, LOGIN and PLAIN. If empty, Alertmanager doesn't authenticate to the SMTP server.\n                            type: string\n                          from:\n                            description: The default SMTP From header field.\n                            type: string\n                          hello:\n                            description: The default hostname to identify to the SMTP server.\n                            type: string\n                          requireTLS:\n                            description: |-\n                              The default SMTP TLS requirement.\n                              Note that Go does not support unencrypted connections to remote SMTP endpoints.\n                            type: boolean\n                          smartHost:\n                            description: The default SMTP smarthost used for sending emails.\n                            properties:\n                              host:\n                                description: Defines the host's address, it can be a DNS name or a literal IP address.\n                                minLength: 1\n                                type: string\n                              port:\n                                description: Defines the host's port, it can be a literal port number or a port name.\n                                minLength: 1\n                                type: string\n                            required:\n                            - host\n                            - port\n                            type: object\n                          tlsConfig:\n                            description: The default TLS configuration for SMTP receivers\n                            properties:\n                              ca:\n                                description: Certificate authority used when verifying server certificates.\n                                properties:\n                                  configMap:\n                                    description: ConfigMap containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key to select.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the ConfigMap or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  secret:\n                                    description: Secret containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              cert:\n                                description: Client certificate to present when doing client-authentication.\n                                properties:\n                                  configMap:\n                                    description: ConfigMap containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key to select.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the ConfigMap or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  secret:\n                                    description: Secret containing data to use for the targets.\n                                    properties:\n                                      key:\n                                        description: The key of the secret to select from.  Must be a valid secret key.\n                                        type: string\n                                      name:\n                                        default: \"\"\n                                        description: |-\n                                          Name of the referent.\n                                          This field is effectively required, but due to backwards compatibility is\n                                          allowed to be empty. Instances of this type with an empty value here are\n                                          almost certainly wrong.\n                                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                        type: string\n                                      optional:\n                                        description: Specify whether the Secret or its key must be defined\n                                        type: boolean\n                                    required:\n                                    - key\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                type: object\n                              insecureSkipVerify:\n                                description: Disable target certificate validation.\n                                type: boolean\n                              keySecret:\n                                description: Secret containing the client key file for the targets.\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              maxVersion:\n                                description: |-\n                                  Maximum acceptable TLS version.\n\n                                  It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                                enum:\n                                - TLS10\n                                - TLS11\n                                - TLS12\n                                - TLS13\n                                type: string\n                              minVersion:\n                                description: |-\n                                  Minimum acceptable TLS version.\n\n                                  It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                                enum:\n                                - TLS10\n                                - TLS11\n                                - TLS12\n                                - TLS13\n                                type: string\n                              serverName:\n                                description: Used to verify the hostname for the targets.\n                                type: string\n                            type: object\n                        type: object\n                      telegram:\n                        description: The default Telegram config\n                        properties:\n                          apiURL:\n                            description: |-\n                              The default Telegram API URL.\n\n                              It requires Alertmanager >= v0.24.0.\n                            pattern: ^(http|https)://.+$\n                            type: string\n                        type: object\n                      victorops:\n                        description: The default configuration for VictorOps.\n                        properties:\n                          apiKey:\n                            description: The default VictorOps API Key.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          apiURL:\n                            description: The default VictorOps API URL.\n                            pattern: ^(http|https)://.+$\n                            type: string\n                        type: object\n                      webex:\n                        description: The default configuration for Jira.\n                        properties:\n                          apiURL:\n                            description: |-\n                              The default Webex API URL.\n\n                              It requires Alertmanager >= v0.25.0.\n                            pattern: ^(http|https)://.+$\n                            type: string\n                        type: object\n                      wechat:\n                        description: The default WeChat Config\n                        properties:\n                          apiCorpID:\n                            description: The default WeChat API Corporate ID.\n                            minLength: 1\n                            type: string\n                          apiSecret:\n                            description: The default WeChat API Secret.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          apiURL:\n                            description: |-\n                              The default WeChat API URL.\n                              The default value is \"https://qyapi.weixin.qq.com/cgi-bin/\"\n                            pattern: ^(http|https)://.+$\n                            type: string\n                        type: object\n                    type: object\n                  name:\n                    description: |-\n                      The name of the AlertmanagerConfig resource which is used to generate the Alertmanager configuration.\n                      It must be defined in the same namespace as the Alertmanager object.\n                      The operator will not enforce a `namespace` label for routes and inhibition rules.\n                    minLength: 1\n                    type: string\n                  templates:\n                    description: Custom notification templates.\n                    items:\n                      description: SecretOrConfigMap allows to specify data as a Secret or ConfigMap. Fields are mutually exclusive.\n                      properties:\n                        configMap:\n                          description: ConfigMap containing data to use for the targets.\n                          properties:\n                            key:\n                              description: The key to select.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the ConfigMap or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        secret:\n                          description: Secret containing data to use for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    type: array\n                type: object\n              automountServiceAccountToken:\n                description: |-\n                  AutomountServiceAccountToken indicates whether a service account token should be automatically mounted in the pod.\n                  If the service account has `automountServiceAccountToken: true`, set the field to `false` to opt out of automounting API credentials.\n                type: boolean\n              baseImage:\n                description: |-\n                  Base image that is used to deploy pods, without tag.\n                  Deprecated: use 'image' instead.\n                type: string\n              clusterAdvertiseAddress:\n                description: |-\n                  ClusterAdvertiseAddress is the explicit address to advertise in cluster.\n                  Needs to be provided for non RFC1918 [1] (public) addresses.\n                  [1] RFC1918: https://tools.ietf.org/html/rfc1918\n                type: string\n              clusterGossipInterval:\n                description: Interval between gossip attempts.\n                pattern: ^(0|(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              clusterLabel:\n                description: |-\n                  Defines the identifier that uniquely identifies the Alertmanager cluster.\n                  You should only set it when the Alertmanager cluster includes Alertmanager instances which are external to this Alertmanager resource. In practice, the addresses of the external instances are provided via the `.spec.additionalPeers` field.\n                type: string\n              clusterPeerTimeout:\n                description: Timeout for cluster peering.\n                pattern: ^(0|(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              clusterPushpullInterval:\n                description: Interval between pushpull attempts.\n                pattern: ^(0|(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              clusterTLS:\n                description: |-\n                  Configures the mutual TLS configuration for the Alertmanager cluster's gossip protocol.\n\n                  It requires Alertmanager >= 0.24.0.\n                properties:\n                  client:\n                    description: Client-side configuration for mutual TLS.\n                    properties:\n                      ca:\n                        description: Certificate authority used when verifying server certificates.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      cert:\n                        description: Client certificate to present when doing client-authentication.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      insecureSkipVerify:\n                        description: Disable target certificate validation.\n                        type: boolean\n                      keySecret:\n                        description: Secret containing the client key file for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: |-\n                          Maximum acceptable TLS version.\n\n                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      minVersion:\n                        description: |-\n                          Minimum acceptable TLS version.\n\n                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      serverName:\n                        description: Used to verify the hostname for the targets.\n                        type: string\n                    type: object\n                  server:\n                    description: Server-side configuration for mutual TLS.\n                    properties:\n                      cert:\n                        description: |-\n                          Secret or ConfigMap containing the TLS certificate for the web server.\n\n                          Either `keySecret` or `keyFile` must be defined.\n\n                          It is mutually exclusive with `certFile`.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      certFile:\n                        description: |-\n                          Path to the TLS certificate file in the container for the web server.\n\n                          Either `keySecret` or `keyFile` must be defined.\n\n                          It is mutually exclusive with `cert`.\n                        type: string\n                      cipherSuites:\n                        description: |-\n                          List of supported cipher suites for TLS versions up to TLS 1.2.\n\n                          If not defined, the Go default cipher suites are used.\n                          Available cipher suites are documented in the Go documentation:\n                          https://golang.org/pkg/crypto/tls/#pkg-constants\n                        items:\n                          type: string\n                        type: array\n                      client_ca:\n                        description: |-\n                          Secret or ConfigMap containing the CA certificate for client certificate\n                          authentication to the server.\n\n                          It is mutually exclusive with `clientCAFile`.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      clientAuthType:\n                        description: |-\n                          The server policy for client TLS authentication.\n\n                          For more detail on clientAuth options:\n                          https://golang.org/pkg/crypto/tls/#ClientAuthType\n                        type: string\n                      clientCAFile:\n                        description: |-\n                          Path to the CA certificate file for client certificate authentication to\n                          the server.\n\n                          It is mutually exclusive with `client_ca`.\n                        type: string\n                      curvePreferences:\n                        description: |-\n                          Elliptic curves that will be used in an ECDHE handshake, in preference\n                          order.\n\n                          Available curves are documented in the Go documentation:\n                          https://golang.org/pkg/crypto/tls/#CurveID\n                        items:\n                          type: string\n                        type: array\n                      keyFile:\n                        description: |-\n                          Path to the TLS private key file in the container for the web server.\n\n                          If defined, either `cert` or `certFile` must be defined.\n\n                          It is mutually exclusive with `keySecret`.\n                        type: string\n                      keySecret:\n                        description: |-\n                          Secret containing the TLS private key for the web server.\n\n                          Either `cert` or `certFile` must be defined.\n\n                          It is mutually exclusive with `keyFile`.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: Maximum TLS version that is acceptable.\n                        type: string\n                      minVersion:\n                        description: Minimum TLS version that is acceptable.\n                        type: string\n                      preferServerCipherSuites:\n                        description: |-\n                          Controls whether the server selects the client's most preferred cipher\n                          suite, or the server's most preferred cipher suite.\n\n                          If true then the server's preference, as expressed in\n                          the order of elements in cipherSuites, is used.\n                        type: boolean\n                    type: object\n                required:\n                - client\n                - server\n                type: object\n              configMaps:\n                description: |-\n                  ConfigMaps is a list of ConfigMaps in the same namespace as the Alertmanager\n                  object, which shall be mounted into the Alertmanager Pods.\n                  Each ConfigMap is added to the StatefulSet definition as a volume named `configmap-<configmap-name>`.\n                  The ConfigMaps are mounted into `/etc/alertmanager/configmaps/<configmap-name>` in the 'alertmanager' container.\n                items:\n                  type: string\n                type: array\n              configSecret:\n                description: |-\n                  ConfigSecret is the name of a Kubernetes Secret in the same namespace as the\n                  Alertmanager object, which contains the configuration for this Alertmanager\n                  instance. If empty, it defaults to `alertmanager-<alertmanager-name>`.\n\n                  The Alertmanager configuration should be available under the\n                  `alertmanager.yaml` key. Additional keys from the original secret are\n                  copied to the generated secret and mounted into the\n                  `/etc/alertmanager/config` directory in the `alertmanager` container.\n\n                  If either the secret or the `alertmanager.yaml` key is missing, the\n                  operator provisions a minimal Alertmanager configuration with one empty\n                  receiver (effectively dropping alert notifications).\n                type: string\n              containers:\n                description: |-\n                  Containers allows injecting additional containers. This is meant to\n                  allow adding an authentication proxy to an Alertmanager pod.\n                  Containers described here modify an operator generated container if they\n                  share the same name and modifications are done via a strategic merge\n                  patch. The current container names are: `alertmanager` and\n                  `config-reloader`. Overriding containers is entirely outside the scope\n                  of what the maintainers will support and by doing so, you accept that\n                  this behaviour may break at any time without notice.\n                items:\n                  description: A single application container that you want to run within a pod.\n                  properties:\n                    args:\n                      description: |-\n                        Arguments to the entrypoint.\n                        The container image's CMD is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    command:\n                      description: |-\n                        Entrypoint array. Not executed within a shell.\n                        The container image's ENTRYPOINT is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    env:\n                      description: |-\n                        List of environment variables to set in the container.\n                        Cannot be updated.\n                      items:\n                        description: EnvVar represents an environment variable present in a Container.\n                        properties:\n                          name:\n                            description: Name of the environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          value:\n                            description: |-\n                              Variable references $(VAR_NAME) are expanded\n                              using the previously defined environment variables in the container and\n                              any service environment variables. If a variable cannot be resolved,\n                              the reference in the input string will be unchanged. Double $$ are reduced\n                              to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.\n                              \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\".\n                              Escaped references will never be expanded, regardless of whether the variable\n                              exists or not.\n                              Defaults to \"\".\n                            type: string\n                          valueFrom:\n                            description: Source for the environment variable's value. Cannot be used if value is not empty.\n                            properties:\n                              configMapKeyRef:\n                                description: Selects a key of a ConfigMap.\n                                properties:\n                                  key:\n                                    description: The key to select.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the ConfigMap or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              fieldRef:\n                                description: |-\n                                  Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,\n                                  spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.\n                                properties:\n                                  apiVersion:\n                                    description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                    type: string\n                                  fieldPath:\n                                    description: Path of the field to select in the specified API version.\n                                    type: string\n                                required:\n                                - fieldPath\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              resourceFieldRef:\n                                description: |-\n                                  Selects a resource of the container: only resources limits and requests\n                                  (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.\n                                properties:\n                                  containerName:\n                                    description: 'Container name: required for volumes, optional for env vars'\n                                    type: string\n                                  divisor:\n                                    anyOf:\n                                    - type: integer\n                                    - type: string\n                                    description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                    x-kubernetes-int-or-string: true\n                                  resource:\n                                    description: 'Required: resource to select'\n                                    type: string\n                                required:\n                                - resource\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              secretKeyRef:\n                                description: Selects a key of a secret in the pod's namespace\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            type: object\n                        required:\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - name\n                      x-kubernetes-list-type: map\n                    envFrom:\n                      description: |-\n                        List of sources to populate environment variables in the container.\n                        The keys defined within a source must be a C_IDENTIFIER. All invalid keys\n                        will be reported as an event when the container is starting. When a key exists in multiple\n                        sources, the value associated with the last source will take precedence.\n                        Values defined by an Env with a duplicate key will take precedence.\n                        Cannot be updated.\n                      items:\n                        description: EnvFromSource represents the source of a set of ConfigMaps or Secrets\n                        properties:\n                          configMapRef:\n                            description: The ConfigMap to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          prefix:\n                            description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          secretRef:\n                            description: The Secret to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    image:\n                      description: |-\n                        Container image name.\n                        More info: https://kubernetes.io/docs/concepts/containers/images\n                        This field is optional to allow higher level config management to default or override\n                        container images in workload controllers like Deployments and StatefulSets.\n                      type: string\n                    imagePullPolicy:\n                      description: |-\n                        Image pull policy.\n                        One of Always, Never, IfNotPresent.\n                        Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/containers/images#updating-images\n                      type: string\n                    lifecycle:\n                      description: |-\n                        Actions that the management system should take in response to container lifecycle events.\n                        Cannot be updated.\n                      properties:\n                        postStart:\n                          description: |-\n                            PostStart is called immediately after a container is created. If the handler fails,\n                            the container is terminated and restarted according to its restart policy.\n                            Other management of the container blocks until the hook completes.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        preStop:\n                          description: |-\n                            PreStop is called immediately before a container is terminated due to an\n                            API request or management event such as liveness/startup probe failure,\n                            preemption, resource contention, etc. The handler is not called if the\n                            container crashes or exits. The Pod's termination grace period countdown begins before the\n                            PreStop hook is executed. Regardless of the outcome of the handler, the\n                            container will eventually terminate within the Pod's termination grace\n                            period (unless delayed by finalizers). Other management of the container blocks until the hook completes\n                            or until the termination grace period is reached.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        stopSignal:\n                          description: |-\n                            StopSignal defines which signal will be sent to a container when it is being stopped.\n                            If not specified, the default is defined by the container runtime in use.\n                            StopSignal can only be set for Pods with a non-empty .spec.os.name\n                          type: string\n                      type: object\n                    livenessProbe:\n                      description: |-\n                        Periodic probe of container liveness.\n                        Container will be restarted if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    name:\n                      description: |-\n                        Name of the container specified as a DNS_LABEL.\n                        Each container in a pod must have a unique name (DNS_LABEL).\n                        Cannot be updated.\n                      type: string\n                    ports:\n                      description: |-\n                        List of ports to expose from the container. Not specifying a port here\n                        DOES NOT prevent that port from being exposed. Any port which is\n                        listening on the default \"0.0.0.0\" address inside a container will be\n                        accessible from the network.\n                        Modifying this array with strategic merge patch may corrupt the data.\n                        For more information See https://github.com/kubernetes/kubernetes/issues/108255.\n                        Cannot be updated.\n                      items:\n                        description: ContainerPort represents a network port in a single container.\n                        properties:\n                          containerPort:\n                            description: |-\n                              Number of port to expose on the pod's IP address.\n                              This must be a valid port number, 0 < x < 65536.\n                            format: int32\n                            type: integer\n                          hostIP:\n                            description: What host IP to bind the external port to.\n                            type: string\n                          hostPort:\n                            description: |-\n                              Number of port to expose on the host.\n                              If specified, this must be a valid port number, 0 < x < 65536.\n                              If HostNetwork is specified, this must match ContainerPort.\n                              Most containers do not need this.\n                            format: int32\n                            type: integer\n                          name:\n                            description: |-\n                              If specified, this must be an IANA_SVC_NAME and unique within the pod. Each\n                              named port in a pod must have a unique name. Name for the port that can be\n                              referred to by services.\n                            type: string\n                          protocol:\n                            default: TCP\n                            description: |-\n                              Protocol for port. Must be UDP, TCP, or SCTP.\n                              Defaults to \"TCP\".\n                            type: string\n                        required:\n                        - containerPort\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - containerPort\n                      - protocol\n                      x-kubernetes-list-type: map\n                    readinessProbe:\n                      description: |-\n                        Periodic probe of container service readiness.\n                        Container will be removed from service endpoints if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    resizePolicy:\n                      description: Resources resize policy for the container.\n                      items:\n                        description: ContainerResizePolicy represents resource resize policy for the container.\n                        properties:\n                          resourceName:\n                            description: |-\n                              Name of the resource to which this resource resize policy applies.\n                              Supported values: cpu, memory.\n                            type: string\n                          restartPolicy:\n                            description: |-\n                              Restart policy to apply when specified resource is resized.\n                              If not specified, it defaults to NotRequired.\n                            type: string\n                        required:\n                        - resourceName\n                        - restartPolicy\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    resources:\n                      description: |-\n                        Compute Resources required by this container.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                      properties:\n                        claims:\n                          description: |-\n                            Claims lists the names of resources, defined in spec.resourceClaims,\n                            that are used by this container.\n\n                            This is an alpha field and requires enabling the\n                            DynamicResourceAllocation feature gate.\n\n                            This field is immutable. It can only be set for containers.\n                          items:\n                            description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                            properties:\n                              name:\n                                description: |-\n                                  Name must match the name of one entry in pod.spec.resourceClaims of\n                                  the Pod where this field is used. It makes that resource available\n                                  inside a container.\n                                type: string\n                              request:\n                                description: |-\n                                  Request is the name chosen for a request in the referenced claim.\n                                  If empty, everything from the claim is made available, otherwise\n                                  only the result of this request.\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          type: array\n                          x-kubernetes-list-map-keys:\n                          - name\n                          x-kubernetes-list-type: map\n                        limits:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Limits describes the maximum amount of compute resources allowed.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                        requests:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Requests describes the minimum amount of compute resources required.\n                            If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                            otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                      type: object\n                    restartPolicy:\n                      description: |-\n                        RestartPolicy defines the restart behavior of individual containers in a pod.\n                        This field may only be set for init containers, and the only allowed value is \"Always\".\n                        For non-init containers or when this field is not specified,\n                        the restart behavior is defined by the Pod's restart policy and the container type.\n                        Setting the RestartPolicy as \"Always\" for the init container will have the following effect:\n                        this init container will be continually restarted on\n                        exit until all regular containers have terminated. Once all regular\n                        containers have completed, all init containers with restartPolicy \"Always\"\n                        will be shut down. This lifecycle differs from normal init containers and\n                        is often referred to as a \"sidecar\" container. Although this init\n                        container still starts in the init container sequence, it does not wait\n                        for the container to complete before proceeding to the next init\n                        container. Instead, the next init container starts immediately after this\n                        init container is started, or after any startupProbe has successfully\n                        completed.\n                      type: string\n                    securityContext:\n                      description: |-\n                        SecurityContext defines the security options the container should be run with.\n                        If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.\n                        More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/\n                      properties:\n                        allowPrivilegeEscalation:\n                          description: |-\n                            AllowPrivilegeEscalation controls whether a process can gain more\n                            privileges than its parent process. This bool directly controls if\n                            the no_new_privs flag will be set on the container process.\n                            AllowPrivilegeEscalation is true always when the container is:\n                            1) run as Privileged\n                            2) has CAP_SYS_ADMIN\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        appArmorProfile:\n                          description: |-\n                            appArmorProfile is the AppArmor options to use by this container. If set, this profile\n                            overrides the pod's appArmorProfile.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile loaded on the node that should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must match the loaded name of the profile.\n                                Must be set if and only if type is \"Localhost\".\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of AppArmor profile will be applied.\n                                Valid options are:\n                                  Localhost - a profile pre-loaded on the node.\n                                  RuntimeDefault - the container runtime's default profile.\n                                  Unconfined - no AppArmor enforcement.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        capabilities:\n                          description: |-\n                            The capabilities to add/drop when running containers.\n                            Defaults to the default set of capabilities granted by the container runtime.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            add:\n                              description: Added capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            drop:\n                              description: Removed capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        privileged:\n                          description: |-\n                            Run container in privileged mode.\n                            Processes in privileged containers are essentially equivalent to root on the host.\n                            Defaults to false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        procMount:\n                          description: |-\n                            procMount denotes the type of proc mount to use for the containers.\n                            The default value is Default which uses the container runtime defaults for\n                            readonly paths and masked paths.\n                            This requires the ProcMountType feature flag to be enabled.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: string\n                        readOnlyRootFilesystem:\n                          description: |-\n                            Whether this container has a read-only root filesystem.\n                            Default is false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        runAsGroup:\n                          description: |-\n                            The GID to run the entrypoint of the container process.\n                            Uses runtime default if unset.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        runAsNonRoot:\n                          description: |-\n                            Indicates that the container must run as a non-root user.\n                            If true, the Kubelet will validate the image at runtime to ensure that it\n                            does not run as UID 0 (root) and fail to start the container if it does.\n                            If unset or false, no such validation will be performed.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                          type: boolean\n                        runAsUser:\n                          description: |-\n                            The UID to run the entrypoint of the container process.\n                            Defaults to user specified in image metadata if unspecified.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        seLinuxOptions:\n                          description: |-\n                            The SELinux context to be applied to the container.\n                            If unspecified, the container runtime will allocate a random SELinux context for each\n                            container.  May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            level:\n                              description: Level is SELinux level label that applies to the container.\n                              type: string\n                            role:\n                              description: Role is a SELinux role label that applies to the container.\n                              type: string\n                            type:\n                              description: Type is a SELinux type label that applies to the container.\n                              type: string\n                            user:\n                              description: User is a SELinux user label that applies to the container.\n                              type: string\n                          type: object\n                        seccompProfile:\n                          description: |-\n                            The seccomp options to use by this container. If seccomp options are\n                            provided at both the pod & container level, the container options\n                            override the pod options.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile defined in a file on the node should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must be a descending path, relative to the kubelet's configured seccomp profile location.\n                                Must be set if type is \"Localhost\". Must NOT be set for any other type.\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of seccomp profile will be applied.\n                                Valid options are:\n\n                                Localhost - a profile defined in a file on the node should be used.\n                                RuntimeDefault - the container runtime default profile should be used.\n                                Unconfined - no profile should be applied.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        windowsOptions:\n                          description: |-\n                            The Windows specific settings applied to all containers.\n                            If unspecified, the options from the PodSecurityContext will be used.\n                            If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is linux.\n                          properties:\n                            gmsaCredentialSpec:\n                              description: |-\n                                GMSACredentialSpec is where the GMSA admission webhook\n                                (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the\n                                GMSA credential spec named by the GMSACredentialSpecName field.\n                              type: string\n                            gmsaCredentialSpecName:\n                              description: GMSACredentialSpecName is the name of the GMSA credential spec to use.\n                              type: string\n                            hostProcess:\n                              description: |-\n                                HostProcess determines if a container should be run as a 'Host Process' container.\n                                All of a Pod's containers must have the same effective HostProcess value\n                                (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).\n                                In addition, if HostProcess is true then HostNetwork must also be set to true.\n                              type: boolean\n                            runAsUserName:\n                              description: |-\n                                The UserName in Windows to run the entrypoint of the container process.\n                                Defaults to the user specified in image metadata if unspecified.\n                                May also be set in PodSecurityContext. If set in both SecurityContext and\n                                PodSecurityContext, the value specified in SecurityContext takes precedence.\n                              type: string\n                          type: object\n                      type: object\n                    startupProbe:\n                      description: |-\n                        StartupProbe indicates that the Pod has successfully initialized.\n                        If specified, no other probes are executed until this completes successfully.\n                        If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.\n                        This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,\n                        when it might take a long time to load data or warm a cache, than during steady-state operation.\n                        This cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    stdin:\n                      description: |-\n                        Whether this container should allocate a buffer for stdin in the container runtime. If this\n                        is not set, reads from stdin in the container will always result in EOF.\n                        Default is false.\n                      type: boolean\n                    stdinOnce:\n                      description: |-\n                        Whether the container runtime should close the stdin channel after it has been opened by\n                        a single attach. When stdin is true the stdin stream will remain open across multiple attach\n                        sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the\n                        first client attaches to stdin, and then remains open and accepts data until the client disconnects,\n                        at which time stdin is closed and remains closed until the container is restarted. If this\n                        flag is false, a container processes that reads from stdin will never receive an EOF.\n                        Default is false\n                      type: boolean\n                    terminationMessagePath:\n                      description: |-\n                        Optional: Path at which the file to which the container's termination message\n                        will be written is mounted into the container's filesystem.\n                        Message written is intended to be brief final status, such as an assertion failure message.\n                        Will be truncated by the node if greater than 4096 bytes. The total message length across\n                        all containers will be limited to 12kb.\n                        Defaults to /dev/termination-log.\n                        Cannot be updated.\n                      type: string\n                    terminationMessagePolicy:\n                      description: |-\n                        Indicate how the termination message should be populated. File will use the contents of\n                        terminationMessagePath to populate the container status message on both success and failure.\n                        FallbackToLogsOnError will use the last chunk of container log output if the termination\n                        message file is empty and the container exited with an error.\n                        The log output is limited to 2048 bytes or 80 lines, whichever is smaller.\n                        Defaults to File.\n                        Cannot be updated.\n                      type: string\n                    tty:\n                      description: |-\n                        Whether this container should allocate a TTY for itself, also requires 'stdin' to be true.\n                        Default is false.\n                      type: boolean\n                    volumeDevices:\n                      description: volumeDevices is the list of block devices to be used by the container.\n                      items:\n                        description: volumeDevice describes a mapping of a raw block device within a container.\n                        properties:\n                          devicePath:\n                            description: devicePath is the path inside of the container that the device will be mapped to.\n                            type: string\n                          name:\n                            description: name must match the name of a persistentVolumeClaim in the pod\n                            type: string\n                        required:\n                        - devicePath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - devicePath\n                      x-kubernetes-list-type: map\n                    volumeMounts:\n                      description: |-\n                        Pod volumes to mount into the container's filesystem.\n                        Cannot be updated.\n                      items:\n                        description: VolumeMount describes a mounting of a Volume within a container.\n                        properties:\n                          mountPath:\n                            description: |-\n                              Path within the container at which the volume should be mounted.  Must\n                              not contain ':'.\n                            type: string\n                          mountPropagation:\n                            description: |-\n                              mountPropagation determines how mounts are propagated from the host\n                              to container and the other way around.\n                              When not set, MountPropagationNone is used.\n                              This field is beta in 1.10.\n                              When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                              (which defaults to None).\n                            type: string\n                          name:\n                            description: This must match the Name of a Volume.\n                            type: string\n                          readOnly:\n                            description: |-\n                              Mounted read-only if true, read-write otherwise (false or unspecified).\n                              Defaults to false.\n                            type: boolean\n                          recursiveReadOnly:\n                            description: |-\n                              RecursiveReadOnly specifies whether read-only mounts should be handled\n                              recursively.\n\n                              If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                              If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                              recursively read-only.  If this field is set to IfPossible, the mount is made\n                              recursively read-only, if it is supported by the container runtime.  If this\n                              field is set to Enabled, the mount is made recursively read-only if it is\n                              supported by the container runtime, otherwise the pod will not be started and\n                              an error will be generated to indicate the reason.\n\n                              If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                              None (or be unspecified, which defaults to None).\n\n                              If this field is not specified, it is treated as an equivalent of Disabled.\n                            type: string\n                          subPath:\n                            description: |-\n                              Path within the volume from which the container's volume should be mounted.\n                              Defaults to \"\" (volume's root).\n                            type: string\n                          subPathExpr:\n                            description: |-\n                              Expanded path within the volume from which the container's volume should be mounted.\n                              Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                              Defaults to \"\" (volume's root).\n                              SubPathExpr and SubPath are mutually exclusive.\n                            type: string\n                        required:\n                        - mountPath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - mountPath\n                      x-kubernetes-list-type: map\n                    workingDir:\n                      description: |-\n                        Container's working directory.\n                        If not specified, the container runtime's default will be used, which\n                        might be configured in the container image.\n                        Cannot be updated.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                type: array\n              dnsConfig:\n                description: Defines the DNS configuration for the pods.\n                properties:\n                  nameservers:\n                    description: |-\n                      A list of DNS name server IP addresses.\n                      This will be appended to the base nameservers generated from DNSPolicy.\n                    items:\n                      minLength: 1\n                      type: string\n                    type: array\n                    x-kubernetes-list-type: set\n                  options:\n                    description: |-\n                      A list of DNS resolver options.\n                      This will be merged with the base options generated from DNSPolicy.\n                      Resolution options given in Options\n                      will override those that appear in the base DNSPolicy.\n                    items:\n                      description: PodDNSConfigOption defines DNS resolver options of a pod.\n                      properties:\n                        name:\n                          description: Name is required and must be unique.\n                          minLength: 1\n                          type: string\n                        value:\n                          description: Value is optional.\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    type: array\n                    x-kubernetes-list-map-keys:\n                    - name\n                    x-kubernetes-list-type: map\n                  searches:\n                    description: |-\n                      A list of DNS search domains for host-name lookup.\n                      This will be appended to the base search paths generated from DNSPolicy.\n                    items:\n                      minLength: 1\n                      type: string\n                    type: array\n                    x-kubernetes-list-type: set\n                type: object\n              dnsPolicy:\n                description: Defines the DNS policy for the pods.\n                enum:\n                - ClusterFirstWithHostNet\n                - ClusterFirst\n                - Default\n                - None\n                type: string\n              enableFeatures:\n                description: |-\n                  Enable access to Alertmanager feature flags. By default, no features are enabled.\n                  Enabling features which are disabled by default is entirely outside the\n                  scope of what the maintainers will support and by doing so, you accept\n                  that this behaviour may break at any time without notice.\n\n                  It requires Alertmanager >= 0.27.0.\n                items:\n                  type: string\n                type: array\n              enableServiceLinks:\n                description: Indicates whether information about services should be injected into pod's environment variables\n                type: boolean\n              externalUrl:\n                description: |-\n                  The external URL the Alertmanager instances will be available under. This is\n                  necessary to generate correct URLs. This is necessary if Alertmanager is not\n                  served from root of a DNS name.\n                type: string\n              forceEnableClusterMode:\n                description: |-\n                  ForceEnableClusterMode ensures Alertmanager does not deactivate the cluster mode when running with a single replica.\n                  Use case is e.g. spanning an Alertmanager cluster across Kubernetes clusters with a single replica in each.\n                type: boolean\n              hostAliases:\n                description: Pods' hostAliases configuration\n                items:\n                  description: |-\n                    HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the\n                    pod's hosts file.\n                  properties:\n                    hostnames:\n                      description: Hostnames for the above IP address.\n                      items:\n                        type: string\n                      type: array\n                    ip:\n                      description: IP address of the host file entry.\n                      type: string\n                  required:\n                  - hostnames\n                  - ip\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - ip\n                x-kubernetes-list-type: map\n              hostUsers:\n                description: |-\n                  HostUsers supports the user space in Kubernetes.\n\n                  More info: https://kubernetes.io/docs/tasks/configure-pod-container/user-namespaces/\n\n                  The feature requires at least Kubernetes 1.28 with the `UserNamespacesSupport` feature gate enabled.\n                  Starting Kubernetes 1.33, the feature is enabled by default.\n                type: boolean\n              image:\n                description: |-\n                  Image if specified has precedence over baseImage, tag and sha\n                  combinations. Specifying the version is still necessary to ensure the\n                  Prometheus Operator knows what version of Alertmanager is being\n                  configured.\n                type: string\n              imagePullPolicy:\n                description: |-\n                  Image pull policy for the 'alertmanager', 'init-config-reloader' and 'config-reloader' containers.\n                  See https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy for more details.\n                enum:\n                - \"\"\n                - Always\n                - Never\n                - IfNotPresent\n                type: string\n              imagePullSecrets:\n                description: |-\n                  An optional list of references to secrets in the same namespace\n                  to use for pulling prometheus and alertmanager images from registries\n                  see https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/\n                items:\n                  description: |-\n                    LocalObjectReference contains enough information to let you locate the\n                    referenced object inside the same namespace.\n                  properties:\n                    name:\n                      default: \"\"\n                      description: |-\n                        Name of the referent.\n                        This field is effectively required, but due to backwards compatibility is\n                        allowed to be empty. Instances of this type with an empty value here are\n                        almost certainly wrong.\n                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                      type: string\n                  type: object\n                  x-kubernetes-map-type: atomic\n                type: array\n              initContainers:\n                description: |-\n                  InitContainers allows adding initContainers to the pod definition. Those can be used to e.g.\n                  fetch secrets for injection into the Alertmanager configuration from external sources. Any\n                  errors during the execution of an initContainer will lead to a restart of the Pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/\n                  InitContainers described here modify an operator\n                  generated init containers if they share the same name and modifications are\n                  done via a strategic merge patch. The current init container name is:\n                  `init-config-reloader`. Overriding init containers is entirely outside the\n                  scope of what the maintainers will support and by doing so, you accept that\n                  this behaviour may break at any time without notice.\n                items:\n                  description: A single application container that you want to run within a pod.\n                  properties:\n                    args:\n                      description: |-\n                        Arguments to the entrypoint.\n                        The container image's CMD is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    command:\n                      description: |-\n                        Entrypoint array. Not executed within a shell.\n                        The container image's ENTRYPOINT is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    env:\n                      description: |-\n                        List of environment variables to set in the container.\n                        Cannot be updated.\n                      items:\n                        description: EnvVar represents an environment variable present in a Container.\n                        properties:\n                          name:\n                            description: Name of the environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          value:\n                            description: |-\n                              Variable references $(VAR_NAME) are expanded\n                              using the previously defined environment variables in the container and\n                              any service environment variables. If a variable cannot be resolved,\n                              the reference in the input string will be unchanged. Double $$ are reduced\n                              to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.\n                              \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\".\n                              Escaped references will never be expanded, regardless of whether the variable\n                              exists or not.\n                              Defaults to \"\".\n                            type: string\n                          valueFrom:\n                            description: Source for the environment variable's value. Cannot be used if value is not empty.\n                            properties:\n                              configMapKeyRef:\n                                description: Selects a key of a ConfigMap.\n                                properties:\n                                  key:\n                                    description: The key to select.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the ConfigMap or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              fieldRef:\n                                description: |-\n                                  Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,\n                                  spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.\n                                properties:\n                                  apiVersion:\n                                    description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                    type: string\n                                  fieldPath:\n                                    description: Path of the field to select in the specified API version.\n                                    type: string\n                                required:\n                                - fieldPath\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              resourceFieldRef:\n                                description: |-\n                                  Selects a resource of the container: only resources limits and requests\n                                  (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.\n                                properties:\n                                  containerName:\n                                    description: 'Container name: required for volumes, optional for env vars'\n                                    type: string\n                                  divisor:\n                                    anyOf:\n                                    - type: integer\n                                    - type: string\n                                    description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                    x-kubernetes-int-or-string: true\n                                  resource:\n                                    description: 'Required: resource to select'\n                                    type: string\n                                required:\n                                - resource\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              secretKeyRef:\n                                description: Selects a key of a secret in the pod's namespace\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            type: object\n                        required:\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - name\n                      x-kubernetes-list-type: map\n                    envFrom:\n                      description: |-\n                        List of sources to populate environment variables in the container.\n                        The keys defined within a source must be a C_IDENTIFIER. All invalid keys\n                        will be reported as an event when the container is starting. When a key exists in multiple\n                        sources, the value associated with the last source will take precedence.\n                        Values defined by an Env with a duplicate key will take precedence.\n                        Cannot be updated.\n                      items:\n                        description: EnvFromSource represents the source of a set of ConfigMaps or Secrets\n                        properties:\n                          configMapRef:\n                            description: The ConfigMap to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          prefix:\n                            description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          secretRef:\n                            description: The Secret to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    image:\n                      description: |-\n                        Container image name.\n                        More info: https://kubernetes.io/docs/concepts/containers/images\n                        This field is optional to allow higher level config management to default or override\n                        container images in workload controllers like Deployments and StatefulSets.\n                      type: string\n                    imagePullPolicy:\n                      description: |-\n                        Image pull policy.\n                        One of Always, Never, IfNotPresent.\n                        Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/containers/images#updating-images\n                      type: string\n                    lifecycle:\n                      description: |-\n                        Actions that the management system should take in response to container lifecycle events.\n                        Cannot be updated.\n                      properties:\n                        postStart:\n                          description: |-\n                            PostStart is called immediately after a container is created. If the handler fails,\n                            the container is terminated and restarted according to its restart policy.\n                            Other management of the container blocks until the hook completes.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        preStop:\n                          description: |-\n                            PreStop is called immediately before a container is terminated due to an\n                            API request or management event such as liveness/startup probe failure,\n                            preemption, resource contention, etc. The handler is not called if the\n                            container crashes or exits. The Pod's termination grace period countdown begins before the\n                            PreStop hook is executed. Regardless of the outcome of the handler, the\n                            container will eventually terminate within the Pod's termination grace\n                            period (unless delayed by finalizers). Other management of the container blocks until the hook completes\n                            or until the termination grace period is reached.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        stopSignal:\n                          description: |-\n                            StopSignal defines which signal will be sent to a container when it is being stopped.\n                            If not specified, the default is defined by the container runtime in use.\n                            StopSignal can only be set for Pods with a non-empty .spec.os.name\n                          type: string\n                      type: object\n                    livenessProbe:\n                      description: |-\n                        Periodic probe of container liveness.\n                        Container will be restarted if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    name:\n                      description: |-\n                        Name of the container specified as a DNS_LABEL.\n                        Each container in a pod must have a unique name (DNS_LABEL).\n                        Cannot be updated.\n                      type: string\n                    ports:\n                      description: |-\n                        List of ports to expose from the container. Not specifying a port here\n                        DOES NOT prevent that port from being exposed. Any port which is\n                        listening on the default \"0.0.0.0\" address inside a container will be\n                        accessible from the network.\n                        Modifying this array with strategic merge patch may corrupt the data.\n                        For more information See https://github.com/kubernetes/kubernetes/issues/108255.\n                        Cannot be updated.\n                      items:\n                        description: ContainerPort represents a network port in a single container.\n                        properties:\n                          containerPort:\n                            description: |-\n                              Number of port to expose on the pod's IP address.\n                              This must be a valid port number, 0 < x < 65536.\n                            format: int32\n                            type: integer\n                          hostIP:\n                            description: What host IP to bind the external port to.\n                            type: string\n                          hostPort:\n                            description: |-\n                              Number of port to expose on the host.\n                              If specified, this must be a valid port number, 0 < x < 65536.\n                              If HostNetwork is specified, this must match ContainerPort.\n                              Most containers do not need this.\n                            format: int32\n                            type: integer\n                          name:\n                            description: |-\n                              If specified, this must be an IANA_SVC_NAME and unique within the pod. Each\n                              named port in a pod must have a unique name. Name for the port that can be\n                              referred to by services.\n                            type: string\n                          protocol:\n                            default: TCP\n                            description: |-\n                              Protocol for port. Must be UDP, TCP, or SCTP.\n                              Defaults to \"TCP\".\n                            type: string\n                        required:\n                        - containerPort\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - containerPort\n                      - protocol\n                      x-kubernetes-list-type: map\n                    readinessProbe:\n                      description: |-\n                        Periodic probe of container service readiness.\n                        Container will be removed from service endpoints if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    resizePolicy:\n                      description: Resources resize policy for the container.\n                      items:\n                        description: ContainerResizePolicy represents resource resize policy for the container.\n                        properties:\n                          resourceName:\n                            description: |-\n                              Name of the resource to which this resource resize policy applies.\n                              Supported values: cpu, memory.\n                            type: string\n                          restartPolicy:\n                            description: |-\n                              Restart policy to apply when specified resource is resized.\n                              If not specified, it defaults to NotRequired.\n                            type: string\n                        required:\n                        - resourceName\n                        - restartPolicy\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    resources:\n                      description: |-\n                        Compute Resources required by this container.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                      properties:\n                        claims:\n                          description: |-\n                            Claims lists the names of resources, defined in spec.resourceClaims,\n                            that are used by this container.\n\n                            This is an alpha field and requires enabling the\n                            DynamicResourceAllocation feature gate.\n\n                            This field is immutable. It can only be set for containers.\n                          items:\n                            description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                            properties:\n                              name:\n                                description: |-\n                                  Name must match the name of one entry in pod.spec.resourceClaims of\n                                  the Pod where this field is used. It makes that resource available\n                                  inside a container.\n                                type: string\n                              request:\n                                description: |-\n                                  Request is the name chosen for a request in the referenced claim.\n                                  If empty, everything from the claim is made available, otherwise\n                                  only the result of this request.\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          type: array\n                          x-kubernetes-list-map-keys:\n                          - name\n                          x-kubernetes-list-type: map\n                        limits:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Limits describes the maximum amount of compute resources allowed.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                        requests:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Requests describes the minimum amount of compute resources required.\n                            If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                            otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                      type: object\n                    restartPolicy:\n                      description: |-\n                        RestartPolicy defines the restart behavior of individual containers in a pod.\n                        This field may only be set for init containers, and the only allowed value is \"Always\".\n                        For non-init containers or when this field is not specified,\n                        the restart behavior is defined by the Pod's restart policy and the container type.\n                        Setting the RestartPolicy as \"Always\" for the init container will have the following effect:\n                        this init container will be continually restarted on\n                        exit until all regular containers have terminated. Once all regular\n                        containers have completed, all init containers with restartPolicy \"Always\"\n                        will be shut down. This lifecycle differs from normal init containers and\n                        is often referred to as a \"sidecar\" container. Although this init\n                        container still starts in the init container sequence, it does not wait\n                        for the container to complete before proceeding to the next init\n                        container. Instead, the next init container starts immediately after this\n                        init container is started, or after any startupProbe has successfully\n                        completed.\n                      type: string\n                    securityContext:\n                      description: |-\n                        SecurityContext defines the security options the container should be run with.\n                        If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.\n                        More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/\n                      properties:\n                        allowPrivilegeEscalation:\n                          description: |-\n                            AllowPrivilegeEscalation controls whether a process can gain more\n                            privileges than its parent process. This bool directly controls if\n                            the no_new_privs flag will be set on the container process.\n                            AllowPrivilegeEscalation is true always when the container is:\n                            1) run as Privileged\n                            2) has CAP_SYS_ADMIN\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        appArmorProfile:\n                          description: |-\n                            appArmorProfile is the AppArmor options to use by this container. If set, this profile\n                            overrides the pod's appArmorProfile.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile loaded on the node that should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must match the loaded name of the profile.\n                                Must be set if and only if type is \"Localhost\".\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of AppArmor profile will be applied.\n                                Valid options are:\n                                  Localhost - a profile pre-loaded on the node.\n                                  RuntimeDefault - the container runtime's default profile.\n                                  Unconfined - no AppArmor enforcement.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        capabilities:\n                          description: |-\n                            The capabilities to add/drop when running containers.\n                            Defaults to the default set of capabilities granted by the container runtime.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            add:\n                              description: Added capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            drop:\n                              description: Removed capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        privileged:\n                          description: |-\n                            Run container in privileged mode.\n                            Processes in privileged containers are essentially equivalent to root on the host.\n                            Defaults to false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        procMount:\n                          description: |-\n                            procMount denotes the type of proc mount to use for the containers.\n                            The default value is Default which uses the container runtime defaults for\n                            readonly paths and masked paths.\n                            This requires the ProcMountType feature flag to be enabled.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: string\n                        readOnlyRootFilesystem:\n                          description: |-\n                            Whether this container has a read-only root filesystem.\n                            Default is false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        runAsGroup:\n                          description: |-\n                            The GID to run the entrypoint of the container process.\n                            Uses runtime default if unset.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        runAsNonRoot:\n                          description: |-\n                            Indicates that the container must run as a non-root user.\n                            If true, the Kubelet will validate the image at runtime to ensure that it\n                            does not run as UID 0 (root) and fail to start the container if it does.\n                            If unset or false, no such validation will be performed.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                          type: boolean\n                        runAsUser:\n                          description: |-\n                            The UID to run the entrypoint of the container process.\n                            Defaults to user specified in image metadata if unspecified.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        seLinuxOptions:\n                          description: |-\n                            The SELinux context to be applied to the container.\n                            If unspecified, the container runtime will allocate a random SELinux context for each\n                            container.  May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            level:\n                              description: Level is SELinux level label that applies to the container.\n                              type: string\n                            role:\n                              description: Role is a SELinux role label that applies to the container.\n                              type: string\n                            type:\n                              description: Type is a SELinux type label that applies to the container.\n                              type: string\n                            user:\n                              description: User is a SELinux user label that applies to the container.\n                              type: string\n                          type: object\n                        seccompProfile:\n                          description: |-\n                            The seccomp options to use by this container. If seccomp options are\n                            provided at both the pod & container level, the container options\n                            override the pod options.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile defined in a file on the node should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must be a descending path, relative to the kubelet's configured seccomp profile location.\n                                Must be set if type is \"Localhost\". Must NOT be set for any other type.\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of seccomp profile will be applied.\n                                Valid options are:\n\n                                Localhost - a profile defined in a file on the node should be used.\n                                RuntimeDefault - the container runtime default profile should be used.\n                                Unconfined - no profile should be applied.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        windowsOptions:\n                          description: |-\n                            The Windows specific settings applied to all containers.\n                            If unspecified, the options from the PodSecurityContext will be used.\n                            If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is linux.\n                          properties:\n                            gmsaCredentialSpec:\n                              description: |-\n                                GMSACredentialSpec is where the GMSA admission webhook\n                                (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the\n                                GMSA credential spec named by the GMSACredentialSpecName field.\n                              type: string\n                            gmsaCredentialSpecName:\n                              description: GMSACredentialSpecName is the name of the GMSA credential spec to use.\n                              type: string\n                            hostProcess:\n                              description: |-\n                                HostProcess determines if a container should be run as a 'Host Process' container.\n                                All of a Pod's containers must have the same effective HostProcess value\n                                (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).\n                                In addition, if HostProcess is true then HostNetwork must also be set to true.\n                              type: boolean\n                            runAsUserName:\n                              description: |-\n                                The UserName in Windows to run the entrypoint of the container process.\n                                Defaults to the user specified in image metadata if unspecified.\n                                May also be set in PodSecurityContext. If set in both SecurityContext and\n                                PodSecurityContext, the value specified in SecurityContext takes precedence.\n                              type: string\n                          type: object\n                      type: object\n                    startupProbe:\n                      description: |-\n                        StartupProbe indicates that the Pod has successfully initialized.\n                        If specified, no other probes are executed until this completes successfully.\n                        If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.\n                        This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,\n                        when it might take a long time to load data or warm a cache, than during steady-state operation.\n                        This cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    stdin:\n                      description: |-\n                        Whether this container should allocate a buffer for stdin in the container runtime. If this\n                        is not set, reads from stdin in the container will always result in EOF.\n                        Default is false.\n                      type: boolean\n                    stdinOnce:\n                      description: |-\n                        Whether the container runtime should close the stdin channel after it has been opened by\n                        a single attach. When stdin is true the stdin stream will remain open across multiple attach\n                        sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the\n                        first client attaches to stdin, and then remains open and accepts data until the client disconnects,\n                        at which time stdin is closed and remains closed until the container is restarted. If this\n                        flag is false, a container processes that reads from stdin will never receive an EOF.\n                        Default is false\n                      type: boolean\n                    terminationMessagePath:\n                      description: |-\n                        Optional: Path at which the file to which the container's termination message\n                        will be written is mounted into the container's filesystem.\n                        Message written is intended to be brief final status, such as an assertion failure message.\n                        Will be truncated by the node if greater than 4096 bytes. The total message length across\n                        all containers will be limited to 12kb.\n                        Defaults to /dev/termination-log.\n                        Cannot be updated.\n                      type: string\n                    terminationMessagePolicy:\n                      description: |-\n                        Indicate how the termination message should be populated. File will use the contents of\n                        terminationMessagePath to populate the container status message on both success and failure.\n                        FallbackToLogsOnError will use the last chunk of container log output if the termination\n                        message file is empty and the container exited with an error.\n                        The log output is limited to 2048 bytes or 80 lines, whichever is smaller.\n                        Defaults to File.\n                        Cannot be updated.\n                      type: string\n                    tty:\n                      description: |-\n                        Whether this container should allocate a TTY for itself, also requires 'stdin' to be true.\n                        Default is false.\n                      type: boolean\n                    volumeDevices:\n                      description: volumeDevices is the list of block devices to be used by the container.\n                      items:\n                        description: volumeDevice describes a mapping of a raw block device within a container.\n                        properties:\n                          devicePath:\n                            description: devicePath is the path inside of the container that the device will be mapped to.\n                            type: string\n                          name:\n                            description: name must match the name of a persistentVolumeClaim in the pod\n                            type: string\n                        required:\n                        - devicePath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - devicePath\n                      x-kubernetes-list-type: map\n                    volumeMounts:\n                      description: |-\n                        Pod volumes to mount into the container's filesystem.\n                        Cannot be updated.\n                      items:\n                        description: VolumeMount describes a mounting of a Volume within a container.\n                        properties:\n                          mountPath:\n                            description: |-\n                              Path within the container at which the volume should be mounted.  Must\n                              not contain ':'.\n                            type: string\n                          mountPropagation:\n                            description: |-\n                              mountPropagation determines how mounts are propagated from the host\n                              to container and the other way around.\n                              When not set, MountPropagationNone is used.\n                              This field is beta in 1.10.\n                              When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                              (which defaults to None).\n                            type: string\n                          name:\n                            description: This must match the Name of a Volume.\n                            type: string\n                          readOnly:\n                            description: |-\n                              Mounted read-only if true, read-write otherwise (false or unspecified).\n                              Defaults to false.\n                            type: boolean\n                          recursiveReadOnly:\n                            description: |-\n                              RecursiveReadOnly specifies whether read-only mounts should be handled\n                              recursively.\n\n                              If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                              If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                              recursively read-only.  If this field is set to IfPossible, the mount is made\n                              recursively read-only, if it is supported by the container runtime.  If this\n                              field is set to Enabled, the mount is made recursively read-only if it is\n                              supported by the container runtime, otherwise the pod will not be started and\n                              an error will be generated to indicate the reason.\n\n                              If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                              None (or be unspecified, which defaults to None).\n\n                              If this field is not specified, it is treated as an equivalent of Disabled.\n                            type: string\n                          subPath:\n                            description: |-\n                              Path within the volume from which the container's volume should be mounted.\n                              Defaults to \"\" (volume's root).\n                            type: string\n                          subPathExpr:\n                            description: |-\n                              Expanded path within the volume from which the container's volume should be mounted.\n                              Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                              Defaults to \"\" (volume's root).\n                              SubPathExpr and SubPath are mutually exclusive.\n                            type: string\n                        required:\n                        - mountPath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - mountPath\n                      x-kubernetes-list-type: map\n                    workingDir:\n                      description: |-\n                        Container's working directory.\n                        If not specified, the container runtime's default will be used, which\n                        might be configured in the container image.\n                        Cannot be updated.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                type: array\n              limits:\n                description: Defines the limits command line flags when starting Alertmanager.\n                properties:\n                  maxPerSilenceBytes:\n                    description: |-\n                      The maximum size of an individual silence as stored on disk. This corresponds to the Alertmanager's\n                      `--silences.max-per-silence-bytes` flag.\n                      It requires Alertmanager >= v0.28.0.\n                    pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$\n                    type: string\n                  maxSilences:\n                    description: |-\n                      The maximum number active and pending silences. This corresponds to the\n                      Alertmanager's `--silences.max-silences` flag.\n                      It requires Alertmanager >= v0.28.0.\n                    format: int32\n                    minimum: 0\n                    type: integer\n                type: object\n              listenLocal:\n                description: |-\n                  ListenLocal makes the Alertmanager server listen on loopback, so that it\n                  does not bind against the Pod IP. Note this is only for the Alertmanager\n                  UI, not the gossip communication.\n                type: boolean\n              logFormat:\n                description: Log format for Alertmanager to be configured with.\n                enum:\n                - \"\"\n                - logfmt\n                - json\n                type: string\n              logLevel:\n                description: Log level for Alertmanager to be configured with.\n                enum:\n                - \"\"\n                - debug\n                - info\n                - warn\n                - error\n                type: string\n              minReadySeconds:\n                description: |-\n                  Minimum number of seconds for which a newly created pod should be ready\n                  without any of its container crashing for it to be considered available.\n\n                  If unset, pods will be considered available as soon as they are ready.\n                format: int32\n                minimum: 0\n                type: integer\n              nodeSelector:\n                additionalProperties:\n                  type: string\n                description: Define which Nodes the Pods are scheduled on.\n                type: object\n              paused:\n                description: |-\n                  If set to true all actions on the underlying managed objects are not\n                  going to be performed, except for delete actions.\n                type: boolean\n              persistentVolumeClaimRetentionPolicy:\n                description: |-\n                  The field controls if and how PVCs are deleted during the lifecycle of a StatefulSet.\n                  The default behavior is all PVCs are retained.\n                  This is an alpha field from kubernetes 1.23 until 1.26 and a beta field from 1.26.\n                  It requires enabling the StatefulSetAutoDeletePVC feature gate.\n                properties:\n                  whenDeleted:\n                    description: |-\n                      WhenDeleted specifies what happens to PVCs created from StatefulSet\n                      VolumeClaimTemplates when the StatefulSet is deleted. The default policy\n                      of `Retain` causes PVCs to not be affected by StatefulSet deletion. The\n                      `Delete` policy causes those PVCs to be deleted.\n                    type: string\n                  whenScaled:\n                    description: |-\n                      WhenScaled specifies what happens to PVCs created from StatefulSet\n                      VolumeClaimTemplates when the StatefulSet is scaled down. The default\n                      policy of `Retain` causes PVCs to not be affected by a scaledown. The\n                      `Delete` policy causes the associated PVCs for any excess pods above\n                      the replica count to be deleted.\n                    type: string\n                type: object\n              podMetadata:\n                description: |-\n                  PodMetadata configures labels and annotations which are propagated to the Alertmanager pods.\n\n                  The following items are reserved and cannot be overridden:\n                  * \"alertmanager\" label, set to the name of the Alertmanager instance.\n                  * \"app.kubernetes.io/instance\" label, set to the name of the Alertmanager instance.\n                  * \"app.kubernetes.io/managed-by\" label, set to \"prometheus-operator\".\n                  * \"app.kubernetes.io/name\" label, set to \"alertmanager\".\n                  * \"app.kubernetes.io/version\" label, set to the Alertmanager version.\n                  * \"kubectl.kubernetes.io/default-container\" annotation, set to \"alertmanager\".\n                properties:\n                  annotations:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      Annotations is an unstructured key value map stored with a resource that may be\n                      set by external tools to store and retrieve arbitrary metadata. They are not\n                      queryable and should be preserved when modifying objects.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/\n                    type: object\n                  labels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      Map of string keys and values that can be used to organize and categorize\n                      (scope and select) objects. May match selectors of replication controllers\n                      and services.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/\n                    type: object\n                  name:\n                    description: |-\n                      Name must be unique within a namespace. Is required when creating resources, although\n                      some resources may allow a client to request the generation of an appropriate name\n                      automatically. Name is primarily intended for creation idempotence and configuration\n                      definition.\n                      Cannot be updated.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\n                    type: string\n                type: object\n              portName:\n                default: web\n                description: |-\n                  Port name used for the pods and governing service.\n                  Defaults to `web`.\n                type: string\n              priorityClassName:\n                description: Priority class assigned to the Pods\n                type: string\n              replicas:\n                description: |-\n                  Size is the expected size of the alertmanager cluster. The controller will\n                  eventually make the size of the running cluster equal to the expected\n                  size.\n                format: int32\n                type: integer\n              resources:\n                description: Define resources requests and limits for single Pods.\n                properties:\n                  claims:\n                    description: |-\n                      Claims lists the names of resources, defined in spec.resourceClaims,\n                      that are used by this container.\n\n                      This is an alpha field and requires enabling the\n                      DynamicResourceAllocation feature gate.\n\n                      This field is immutable. It can only be set for containers.\n                    items:\n                      description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                      properties:\n                        name:\n                          description: |-\n                            Name must match the name of one entry in pod.spec.resourceClaims of\n                            the Pod where this field is used. It makes that resource available\n                            inside a container.\n                          type: string\n                        request:\n                          description: |-\n                            Request is the name chosen for a request in the referenced claim.\n                            If empty, everything from the claim is made available, otherwise\n                            only the result of this request.\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    type: array\n                    x-kubernetes-list-map-keys:\n                    - name\n                    x-kubernetes-list-type: map\n                  limits:\n                    additionalProperties:\n                      anyOf:\n                      - type: integer\n                      - type: string\n                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                      x-kubernetes-int-or-string: true\n                    description: |-\n                      Limits describes the maximum amount of compute resources allowed.\n                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                    type: object\n                  requests:\n                    additionalProperties:\n                      anyOf:\n                      - type: integer\n                      - type: string\n                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                      x-kubernetes-int-or-string: true\n                    description: |-\n                      Requests describes the minimum amount of compute resources required.\n                      If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                      otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                    type: object\n                type: object\n              retention:\n                default: 120h\n                description: |-\n                  Time duration Alertmanager shall retain data for. Default is '120h',\n                  and must match the regular expression `[0-9]+(ms|s|m|h)` (milliseconds seconds minutes hours).\n                pattern: ^(0|(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              routePrefix:\n                description: |-\n                  The route prefix Alertmanager registers HTTP handlers for. This is useful,\n                  if using ExternalURL and a proxy is rewriting HTTP routes of a request,\n                  and the actual ExternalURL is still true, but the server serves requests\n                  under a different route prefix. For example for use with `kubectl proxy`.\n                type: string\n              secrets:\n                description: |-\n                  Secrets is a list of Secrets in the same namespace as the Alertmanager\n                  object, which shall be mounted into the Alertmanager Pods.\n                  Each Secret is added to the StatefulSet definition as a volume named `secret-<secret-name>`.\n                  The Secrets are mounted into `/etc/alertmanager/secrets/<secret-name>` in the 'alertmanager' container.\n                items:\n                  type: string\n                type: array\n              securityContext:\n                description: |-\n                  SecurityContext holds pod-level security attributes and common container settings.\n                  This defaults to the default PodSecurityContext.\n                properties:\n                  appArmorProfile:\n                    description: |-\n                      appArmorProfile is the AppArmor options to use by the containers in this pod.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    properties:\n                      localhostProfile:\n                        description: |-\n                          localhostProfile indicates a profile loaded on the node that should be used.\n                          The profile must be preconfigured on the node to work.\n                          Must match the loaded name of the profile.\n                          Must be set if and only if type is \"Localhost\".\n                        type: string\n                      type:\n                        description: |-\n                          type indicates which kind of AppArmor profile will be applied.\n                          Valid options are:\n                            Localhost - a profile pre-loaded on the node.\n                            RuntimeDefault - the container runtime's default profile.\n                            Unconfined - no AppArmor enforcement.\n                        type: string\n                    required:\n                    - type\n                    type: object\n                  fsGroup:\n                    description: |-\n                      A special supplemental group that applies to all containers in a pod.\n                      Some volume types allow the Kubelet to change the ownership of that volume\n                      to be owned by the pod:\n\n                      1. The owning GID will be the FSGroup\n                      2. The setgid bit is set (new files created in the volume will be owned by FSGroup)\n                      3. The permission bits are OR'd with rw-rw----\n\n                      If unset, the Kubelet will not modify the ownership and permissions of any volume.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    format: int64\n                    type: integer\n                  fsGroupChangePolicy:\n                    description: |-\n                      fsGroupChangePolicy defines behavior of changing ownership and permission of the volume\n                      before being exposed inside Pod. This field will only apply to\n                      volume types which support fsGroup based ownership(and permissions).\n                      It will have no effect on ephemeral volume types such as: secret, configmaps\n                      and emptydir.\n                      Valid values are \"OnRootMismatch\" and \"Always\". If not specified, \"Always\" is used.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    type: string\n                  runAsGroup:\n                    description: |-\n                      The GID to run the entrypoint of the container process.\n                      Uses runtime default if unset.\n                      May also be set in SecurityContext.  If set in both SecurityContext and\n                      PodSecurityContext, the value specified in SecurityContext takes precedence\n                      for that container.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    format: int64\n                    type: integer\n                  runAsNonRoot:\n                    description: |-\n                      Indicates that the container must run as a non-root user.\n                      If true, the Kubelet will validate the image at runtime to ensure that it\n                      does not run as UID 0 (root) and fail to start the container if it does.\n                      If unset or false, no such validation will be performed.\n                      May also be set in SecurityContext.  If set in both SecurityContext and\n                      PodSecurityContext, the value specified in SecurityContext takes precedence.\n                    type: boolean\n                  runAsUser:\n                    description: |-\n                      The UID to run the entrypoint of the container process.\n                      Defaults to user specified in image metadata if unspecified.\n                      May also be set in SecurityContext.  If set in both SecurityContext and\n                      PodSecurityContext, the value specified in SecurityContext takes precedence\n                      for that container.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    format: int64\n                    type: integer\n                  seLinuxChangePolicy:\n                    description: |-\n                      seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod.\n                      It has no effect on nodes that do not support SELinux or to volumes does not support SELinux.\n                      Valid values are \"MountOption\" and \"Recursive\".\n\n                      \"Recursive\" means relabeling of all files on all Pod volumes by the container runtime.\n                      This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.\n\n                      \"MountOption\" mounts all eligible Pod volumes with `-o context` mount option.\n                      This requires all Pods that share the same volume to use the same SELinux label.\n                      It is not possible to share the same volume among privileged and unprivileged Pods.\n                      Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes\n                      whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their\n                      CSIDriver instance. Other volumes are always re-labelled recursively.\n                      \"MountOption\" value is allowed only when SELinuxMount feature gate is enabled.\n\n                      If not specified and SELinuxMount feature gate is enabled, \"MountOption\" is used.\n                      If not specified and SELinuxMount feature gate is disabled, \"MountOption\" is used for ReadWriteOncePod volumes\n                      and \"Recursive\" for all other volumes.\n\n                      This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.\n\n                      All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    type: string\n                  seLinuxOptions:\n                    description: |-\n                      The SELinux context to be applied to all containers.\n                      If unspecified, the container runtime will allocate a random SELinux context for each\n                      container.  May also be set in SecurityContext.  If set in\n                      both SecurityContext and PodSecurityContext, the value specified in SecurityContext\n                      takes precedence for that container.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    properties:\n                      level:\n                        description: Level is SELinux level label that applies to the container.\n                        type: string\n                      role:\n                        description: Role is a SELinux role label that applies to the container.\n                        type: string\n                      type:\n                        description: Type is a SELinux type label that applies to the container.\n                        type: string\n                      user:\n                        description: User is a SELinux user label that applies to the container.\n                        type: string\n                    type: object\n                  seccompProfile:\n                    description: |-\n                      The seccomp options to use by the containers in this pod.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    properties:\n                      localhostProfile:\n                        description: |-\n                          localhostProfile indicates a profile defined in a file on the node should be used.\n                          The profile must be preconfigured on the node to work.\n                          Must be a descending path, relative to the kubelet's configured seccomp profile location.\n                          Must be set if type is \"Localhost\". Must NOT be set for any other type.\n                        type: string\n                      type:\n                        description: |-\n                          type indicates which kind of seccomp profile will be applied.\n                          Valid options are:\n\n                          Localhost - a profile defined in a file on the node should be used.\n                          RuntimeDefault - the container runtime default profile should be used.\n                          Unconfined - no profile should be applied.\n                        type: string\n                    required:\n                    - type\n                    type: object\n                  supplementalGroups:\n                    description: |-\n                      A list of groups applied to the first process run in each container, in\n                      addition to the container's primary GID and fsGroup (if specified).  If\n                      the SupplementalGroupsPolicy feature is enabled, the\n                      supplementalGroupsPolicy field determines whether these are in addition\n                      to or instead of any group memberships defined in the container image.\n                      If unspecified, no additional groups are added, though group memberships\n                      defined in the container image may still be used, depending on the\n                      supplementalGroupsPolicy field.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    items:\n                      format: int64\n                      type: integer\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  supplementalGroupsPolicy:\n                    description: |-\n                      Defines how supplemental groups of the first container processes are calculated.\n                      Valid values are \"Merge\" and \"Strict\". If not specified, \"Merge\" is used.\n                      (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled\n                      and the container runtime must implement support for this feature.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    type: string\n                  sysctls:\n                    description: |-\n                      Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported\n                      sysctls (by the container runtime) might fail to launch.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    items:\n                      description: Sysctl defines a kernel parameter to be set\n                      properties:\n                        name:\n                          description: Name of a property to set\n                          type: string\n                        value:\n                          description: Value of a property to set\n                          type: string\n                      required:\n                      - name\n                      - value\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  windowsOptions:\n                    description: |-\n                      The Windows specific settings applied to all containers.\n                      If unspecified, the options within a container's SecurityContext will be used.\n                      If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.\n                      Note that this field cannot be set when spec.os.name is linux.\n                    properties:\n                      gmsaCredentialSpec:\n                        description: |-\n                          GMSACredentialSpec is where the GMSA admission webhook\n                          (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the\n                          GMSA credential spec named by the GMSACredentialSpecName field.\n                        type: string\n                      gmsaCredentialSpecName:\n                        description: GMSACredentialSpecName is the name of the GMSA credential spec to use.\n                        type: string\n                      hostProcess:\n                        description: |-\n                          HostProcess determines if a container should be run as a 'Host Process' container.\n                          All of a Pod's containers must have the same effective HostProcess value\n                          (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).\n                          In addition, if HostProcess is true then HostNetwork must also be set to true.\n                        type: boolean\n                      runAsUserName:\n                        description: |-\n                          The UserName in Windows to run the entrypoint of the container process.\n                          Defaults to the user specified in image metadata if unspecified.\n                          May also be set in PodSecurityContext. If set in both SecurityContext and\n                          PodSecurityContext, the value specified in SecurityContext takes precedence.\n                        type: string\n                    type: object\n                type: object\n              serviceAccountName:\n                description: |-\n                  ServiceAccountName is the name of the ServiceAccount to use to run the\n                  Prometheus Pods.\n                type: string\n              serviceName:\n                description: |-\n                  The name of the service name used by the underlying StatefulSet(s) as the governing service.\n                  If defined, the Service  must be created before the Alertmanager resource in the same namespace and it must define a selector that matches the pod labels.\n                  If empty, the operator will create and manage a headless service named `alertmanager-operated` for Alermanager resources.\n                  When deploying multiple Alertmanager resources in the same namespace, it is recommended to specify a different value for each.\n                  See https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id for more details.\n                minLength: 1\n                type: string\n              sha:\n                description: |-\n                  SHA of Alertmanager container image to be deployed. Defaults to the value of `version`.\n                  Similar to a tag, but the SHA explicitly deploys an immutable container image.\n                  Version and Tag are ignored if SHA is set.\n                  Deprecated: use 'image' instead. The image digest can be specified as part of the image URL.\n                type: string\n              storage:\n                description: |-\n                  Storage is the definition of how storage will be used by the Alertmanager\n                  instances.\n                properties:\n                  disableMountSubPath:\n                    description: 'Deprecated: subPath usage will be removed in a future release.'\n                    type: boolean\n                  emptyDir:\n                    description: |-\n                      EmptyDirVolumeSource to be used by the StatefulSet.\n                      If specified, it takes precedence over `ephemeral` and `volumeClaimTemplate`.\n                      More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir\n                    properties:\n                      medium:\n                        description: |-\n                          medium represents what type of storage medium should back this directory.\n                          The default is \"\" which means to use the node's default medium.\n                          Must be an empty string (default) or Memory.\n                          More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                        type: string\n                      sizeLimit:\n                        anyOf:\n                        - type: integer\n                        - type: string\n                        description: |-\n                          sizeLimit is the total amount of local storage required for this EmptyDir volume.\n                          The size limit is also applicable for memory medium.\n                          The maximum usage on memory medium EmptyDir would be the minimum value between\n                          the SizeLimit specified here and the sum of memory limits of all containers in a pod.\n                          The default is nil which means that the limit is undefined.\n                          More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                        pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                        x-kubernetes-int-or-string: true\n                    type: object\n                  ephemeral:\n                    description: |-\n                      EphemeralVolumeSource to be used by the StatefulSet.\n                      This is a beta field in k8s 1.21 and GA in 1.15.\n                      For lower versions, starting with k8s 1.19, it requires enabling the GenericEphemeralVolume feature gate.\n                      More info: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes\n                    properties:\n                      volumeClaimTemplate:\n                        description: |-\n                          Will be used to create a stand-alone PVC to provision the volume.\n                          The pod in which this EphemeralVolumeSource is embedded will be the\n                          owner of the PVC, i.e. the PVC will be deleted together with the\n                          pod.  The name of the PVC will be `<pod name>-<volume name>` where\n                          `<volume name>` is the name from the `PodSpec.Volumes` array\n                          entry. Pod validation will reject the pod if the concatenated name\n                          is not valid for a PVC (for example, too long).\n\n                          An existing PVC with that name that is not owned by the pod\n                          will *not* be used for the pod to avoid using an unrelated\n                          volume by mistake. Starting the pod is then blocked until\n                          the unrelated PVC is removed. If such a pre-created PVC is\n                          meant to be used by the pod, the PVC has to updated with an\n                          owner reference to the pod once the pod exists. Normally\n                          this should not be necessary, but it may be useful when\n                          manually reconstructing a broken cluster.\n\n                          This field is read-only and no changes will be made by Kubernetes\n                          to the PVC after it has been created.\n\n                          Required, must not be nil.\n                        properties:\n                          metadata:\n                            description: |-\n                              May contain labels and annotations that will be copied into the PVC\n                              when creating it. No other fields are allowed and will be rejected during\n                              validation.\n                            type: object\n                          spec:\n                            description: |-\n                              The specification for the PersistentVolumeClaim. The entire content is\n                              copied unchanged into the PVC that gets created from this\n                              template. The same fields as in a PersistentVolumeClaim\n                              are also valid here.\n                            properties:\n                              accessModes:\n                                description: |-\n                                  accessModes contains the desired access modes the volume should have.\n                                  More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                                items:\n                                  type: string\n                                type: array\n                                x-kubernetes-list-type: atomic\n                              dataSource:\n                                description: |-\n                                  dataSource field can be used to specify either:\n                                  * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n                                  * An existing PVC (PersistentVolumeClaim)\n                                  If the provisioner or an external controller can support the specified data source,\n                                  it will create a new volume based on the contents of the specified data source.\n                                  When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\n                                  and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\n                                  If the namespace is specified, then dataSourceRef will not be copied to dataSource.\n                                properties:\n                                  apiGroup:\n                                    description: |-\n                                      APIGroup is the group for the resource being referenced.\n                                      If APIGroup is not specified, the specified Kind must be in the core API group.\n                                      For any other third-party types, APIGroup is required.\n                                    type: string\n                                  kind:\n                                    description: Kind is the type of resource being referenced\n                                    type: string\n                                  name:\n                                    description: Name is the name of resource being referenced\n                                    type: string\n                                required:\n                                - kind\n                                - name\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              dataSourceRef:\n                                description: |-\n                                  dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\n                                  volume is desired. This may be any object from a non-empty API group (non\n                                  core object) or a PersistentVolumeClaim object.\n                                  When this field is specified, volume binding will only succeed if the type of\n                                  the specified object matches some installed volume populator or dynamic\n                                  provisioner.\n                                  This field will replace the functionality of the dataSource field and as such\n                                  if both fields are non-empty, they must have the same value. For backwards\n                                  compatibility, when namespace isn't specified in dataSourceRef,\n                                  both fields (dataSource and dataSourceRef) will be set to the same\n                                  value automatically if one of them is empty and the other is non-empty.\n                                  When namespace is specified in dataSourceRef,\n                                  dataSource isn't set to the same value and must be empty.\n                                  There are three important differences between dataSource and dataSourceRef:\n                                  * While dataSource only allows two specific types of objects, dataSourceRef\n                                    allows any non-core object, as well as PersistentVolumeClaim objects.\n                                  * While dataSource ignores disallowed values (dropping them), dataSourceRef\n                                    preserves all values, and generates an error if a disallowed value is\n                                    specified.\n                                  * While dataSource only allows local objects, dataSourceRef allows objects\n                                    in any namespaces.\n                                  (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n                                  (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                properties:\n                                  apiGroup:\n                                    description: |-\n                                      APIGroup is the group for the resource being referenced.\n                                      If APIGroup is not specified, the specified Kind must be in the core API group.\n                                      For any other third-party types, APIGroup is required.\n                                    type: string\n                                  kind:\n                                    description: Kind is the type of resource being referenced\n                                    type: string\n                                  name:\n                                    description: Name is the name of resource being referenced\n                                    type: string\n                                  namespace:\n                                    description: |-\n                                      Namespace is the namespace of resource being referenced\n                                      Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n                                      (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                    type: string\n                                required:\n                                - kind\n                                - name\n                                type: object\n                              resources:\n                                description: |-\n                                  resources represents the minimum resources the volume should have.\n                                  If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\n                                  that are lower than previous value but must still be higher than capacity recorded in the\n                                  status field of the claim.\n                                  More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources\n                                properties:\n                                  limits:\n                                    additionalProperties:\n                                      anyOf:\n                                      - type: integer\n                                      - type: string\n                                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                      x-kubernetes-int-or-string: true\n                                    description: |-\n                                      Limits describes the maximum amount of compute resources allowed.\n                                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                    type: object\n                                  requests:\n                                    additionalProperties:\n                                      anyOf:\n                                      - type: integer\n                                      - type: string\n                                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                      x-kubernetes-int-or-string: true\n                                    description: |-\n                                      Requests describes the minimum amount of compute resources required.\n                                      If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                                      otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                    type: object\n                                type: object\n                              selector:\n                                description: selector is a label query over volumes to consider for binding.\n                                properties:\n                                  matchExpressions:\n                                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                    items:\n                                      description: |-\n                                        A label selector requirement is a selector that contains values, a key, and an operator that\n                                        relates the key and values.\n                                      properties:\n                                        key:\n                                          description: key is the label key that the selector applies to.\n                                          type: string\n                                        operator:\n                                          description: |-\n                                            operator represents a key's relationship to a set of values.\n                                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                                          type: string\n                                        values:\n                                          description: |-\n                                            values is an array of string values. If the operator is In or NotIn,\n                                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                            the values array must be empty. This array is replaced during a strategic\n                                            merge patch.\n                                          items:\n                                            type: string\n                                          type: array\n                                          x-kubernetes-list-type: atomic\n                                      required:\n                                      - key\n                                      - operator\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                  matchLabels:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                    type: object\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              storageClassName:\n                                description: |-\n                                  storageClassName is the name of the StorageClass required by the claim.\n                                  More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1\n                                type: string\n                              volumeAttributesClassName:\n                                description: |-\n                                  volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\n                                  If specified, the CSI driver will create or update the volume with the attributes defined\n                                  in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\n                                  it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\n                                  will be applied to the claim but it's not allowed to reset this field to empty string once it is set.\n                                  If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\n                                  will be set by the persistentvolume controller if it exists.\n                                  If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\n                                  set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\n                                  exists.\n                                  More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n                                  (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).\n                                type: string\n                              volumeMode:\n                                description: |-\n                                  volumeMode defines what type of volume is required by the claim.\n                                  Value of Filesystem is implied when not included in claim spec.\n                                type: string\n                              volumeName:\n                                description: volumeName is the binding reference to the PersistentVolume backing this claim.\n                                type: string\n                            type: object\n                        required:\n                        - spec\n                        type: object\n                    type: object\n                  volumeClaimTemplate:\n                    description: |-\n                      Defines the PVC spec to be used by the Prometheus StatefulSets.\n                      The easiest way to use a volume that cannot be automatically provisioned\n                      is to use a label selector alongside manually created PersistentVolumes.\n                    properties:\n                      apiVersion:\n                        description: |-\n                          APIVersion defines the versioned schema of this representation of an object.\n                          Servers should convert recognized schemas to the latest internal value, and\n                          may reject unrecognized values.\n                          More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n                        type: string\n                      kind:\n                        description: |-\n                          Kind is a string value representing the REST resource this object represents.\n                          Servers may infer this from the endpoint the client submits requests to.\n                          Cannot be updated.\n                          In CamelCase.\n                          More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n                        type: string\n                      metadata:\n                        description: EmbeddedMetadata contains metadata relevant to an EmbeddedResource.\n                        properties:\n                          annotations:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              Annotations is an unstructured key value map stored with a resource that may be\n                              set by external tools to store and retrieve arbitrary metadata. They are not\n                              queryable and should be preserved when modifying objects.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/\n                            type: object\n                          labels:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              Map of string keys and values that can be used to organize and categorize\n                              (scope and select) objects. May match selectors of replication controllers\n                              and services.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/\n                            type: object\n                          name:\n                            description: |-\n                              Name must be unique within a namespace. Is required when creating resources, although\n                              some resources may allow a client to request the generation of an appropriate name\n                              automatically. Name is primarily intended for creation idempotence and configuration\n                              definition.\n                              Cannot be updated.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\n                            type: string\n                        type: object\n                      spec:\n                        description: |-\n                          Defines the desired characteristics of a volume requested by a pod author.\n                          More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims\n                        properties:\n                          accessModes:\n                            description: |-\n                              accessModes contains the desired access modes the volume should have.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                            items:\n                              type: string\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          dataSource:\n                            description: |-\n                              dataSource field can be used to specify either:\n                              * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n                              * An existing PVC (PersistentVolumeClaim)\n                              If the provisioner or an external controller can support the specified data source,\n                              it will create a new volume based on the contents of the specified data source.\n                              When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\n                              and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\n                              If the namespace is specified, then dataSourceRef will not be copied to dataSource.\n                            properties:\n                              apiGroup:\n                                description: |-\n                                  APIGroup is the group for the resource being referenced.\n                                  If APIGroup is not specified, the specified Kind must be in the core API group.\n                                  For any other third-party types, APIGroup is required.\n                                type: string\n                              kind:\n                                description: Kind is the type of resource being referenced\n                                type: string\n                              name:\n                                description: Name is the name of resource being referenced\n                                type: string\n                            required:\n                            - kind\n                            - name\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          dataSourceRef:\n                            description: |-\n                              dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\n                              volume is desired. This may be any object from a non-empty API group (non\n                              core object) or a PersistentVolumeClaim object.\n                              When this field is specified, volume binding will only succeed if the type of\n                              the specified object matches some installed volume populator or dynamic\n                              provisioner.\n                              This field will replace the functionality of the dataSource field and as such\n                              if both fields are non-empty, they must have the same value. For backwards\n                              compatibility, when namespace isn't specified in dataSourceRef,\n                              both fields (dataSource and dataSourceRef) will be set to the same\n                              value automatically if one of them is empty and the other is non-empty.\n                              When namespace is specified in dataSourceRef,\n                              dataSource isn't set to the same value and must be empty.\n                              There are three important differences between dataSource and dataSourceRef:\n                              * While dataSource only allows two specific types of objects, dataSourceRef\n                                allows any non-core object, as well as PersistentVolumeClaim objects.\n                              * While dataSource ignores disallowed values (dropping them), dataSourceRef\n                                preserves all values, and generates an error if a disallowed value is\n                                specified.\n                              * While dataSource only allows local objects, dataSourceRef allows objects\n                                in any namespaces.\n                              (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n                              (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                            properties:\n                              apiGroup:\n                                description: |-\n                                  APIGroup is the group for the resource being referenced.\n                                  If APIGroup is not specified, the specified Kind must be in the core API group.\n                                  For any other third-party types, APIGroup is required.\n                                type: string\n                              kind:\n                                description: Kind is the type of resource being referenced\n                                type: string\n                              name:\n                                description: Name is the name of resource being referenced\n                                type: string\n                              namespace:\n                                description: |-\n                                  Namespace is the namespace of resource being referenced\n                                  Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n                                  (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                type: string\n                            required:\n                            - kind\n                            - name\n                            type: object\n                          resources:\n                            description: |-\n                              resources represents the minimum resources the volume should have.\n                              If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\n                              that are lower than previous value but must still be higher than capacity recorded in the\n                              status field of the claim.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources\n                            properties:\n                              limits:\n                                additionalProperties:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                  x-kubernetes-int-or-string: true\n                                description: |-\n                                  Limits describes the maximum amount of compute resources allowed.\n                                  More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                type: object\n                              requests:\n                                additionalProperties:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                  x-kubernetes-int-or-string: true\n                                description: |-\n                                  Requests describes the minimum amount of compute resources required.\n                                  If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                                  otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                                  More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                type: object\n                            type: object\n                          selector:\n                            description: selector is a label query over volumes to consider for binding.\n                            properties:\n                              matchExpressions:\n                                description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                items:\n                                  description: |-\n                                    A label selector requirement is a selector that contains values, a key, and an operator that\n                                    relates the key and values.\n                                  properties:\n                                    key:\n                                      description: key is the label key that the selector applies to.\n                                      type: string\n                                    operator:\n                                      description: |-\n                                        operator represents a key's relationship to a set of values.\n                                        Valid operators are In, NotIn, Exists and DoesNotExist.\n                                      type: string\n                                    values:\n                                      description: |-\n                                        values is an array of string values. If the operator is In or NotIn,\n                                        the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                        the values array must be empty. This array is replaced during a strategic\n                                        merge patch.\n                                      items:\n                                        type: string\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                  required:\n                                  - key\n                                  - operator\n                                  type: object\n                                type: array\n                                x-kubernetes-list-type: atomic\n                              matchLabels:\n                                additionalProperties:\n                                  type: string\n                                description: |-\n                                  matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                  map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                  operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                type: object\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          storageClassName:\n                            description: |-\n                              storageClassName is the name of the StorageClass required by the claim.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1\n                            type: string\n                          volumeAttributesClassName:\n                            description: |-\n                              volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\n                              If specified, the CSI driver will create or update the volume with the attributes defined\n                              in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\n                              it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\n                              will be applied to the claim but it's not allowed to reset this field to empty string once it is set.\n                              If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\n                              will be set by the persistentvolume controller if it exists.\n                              If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\n                              set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\n                              exists.\n                              More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n                              (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).\n                            type: string\n                          volumeMode:\n                            description: |-\n                              volumeMode defines what type of volume is required by the claim.\n                              Value of Filesystem is implied when not included in claim spec.\n                            type: string\n                          volumeName:\n                            description: volumeName is the binding reference to the PersistentVolume backing this claim.\n                            type: string\n                        type: object\n                      status:\n                        description: 'Deprecated: this field is never set.'\n                        properties:\n                          accessModes:\n                            description: |-\n                              accessModes contains the actual access modes the volume backing the PVC has.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                            items:\n                              type: string\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          allocatedResourceStatuses:\n                            additionalProperties:\n                              description: |-\n                                When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource\n                                that it does not recognizes, then it should ignore that update and let other controllers\n                                handle it.\n                              type: string\n                            description: \"allocatedResourceStatuses stores status of resource being resized for the given PVC.\\nKey names follow standard Kubernetes label syntax. Valid values are either:\\n\\t* Un-prefixed keys:\\n\\t\\t- storage - the capacity of the volume.\\n\\t* Custom resources must use implementation-defined prefixed names such as \\\"example.com/my-custom-resource\\\"\\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\\nreserved and hence may not be used.\\n\\nClaimResourceStatus can be in any of following states:\\n\\t- ControllerResizeInProgress:\\n\\t\\tState set when resize controller starts resizing the volume in control-plane.\\n\\t- ControllerResizeFailed:\\n\\t\\tState set when resize has failed in resize controller with a terminal error.\\n\\t- NodeResizePending:\\n\\t\\tState set when resize controller has finished resizing the volume but further resizing of\\n\\t\\tvolume is needed on the node.\\n\\t- NodeResizeInProgress:\\n\\t\\tState set when kubelet starts resizing the volume.\\n\\t- NodeResizeFailed:\\n\\t\\tState set when resizing has failed in kubelet with a terminal error. Transient errors don't set\\n\\t\\tNodeResizeFailed.\\nFor example: if expanding a PVC for more capacity - this field can be one of the following states:\\n\\t- pvc.status.allocatedResourceStatus['storage'] = \\\"ControllerResizeInProgress\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"ControllerResizeFailed\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"NodeResizePending\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"NodeResizeInProgress\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"NodeResizeFailed\\\"\\nWhen this field is not set, it means that no resize operation is in progress for the given PVC.\\n\\nA controller that receives PVC update with previously unknown resourceName or ClaimResourceStatus\\nshould ignore the update for the purpose it was designed. For example - a controller that\\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\\nresources associated with PVC.\\n\\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.\"\n                            type: object\n                            x-kubernetes-map-type: granular\n                          allocatedResources:\n                            additionalProperties:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                              x-kubernetes-int-or-string: true\n                            description: \"allocatedResources tracks the resources allocated to a PVC including its capacity.\\nKey names follow standard Kubernetes label syntax. Valid values are either:\\n\\t* Un-prefixed keys:\\n\\t\\t- storage - the capacity of the volume.\\n\\t* Custom resources must use implementation-defined prefixed names such as \\\"example.com/my-custom-resource\\\"\\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\\nreserved and hence may not be used.\\n\\nCapacity reported here may be larger than the actual capacity when a volume expansion operation\\nis requested.\\nFor storage quota, the larger value from allocatedResources and PVC.spec.resources is used.\\nIf allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.\\nIf a volume expansion capacity request is lowered, allocatedResources is only\\nlowered if there are no expansion operations in progress and if the actual volume capacity\\nis equal or lower than the requested capacity.\\n\\nA controller that receives PVC update with previously unknown resourceName\\nshould ignore the update for the purpose it was designed. For example - a controller that\\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\\nresources associated with PVC.\\n\\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.\"\n                            type: object\n                          capacity:\n                            additionalProperties:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                              x-kubernetes-int-or-string: true\n                            description: capacity represents the actual resources of the underlying volume.\n                            type: object\n                          conditions:\n                            description: |-\n                              conditions is the current Condition of persistent volume claim. If underlying persistent volume is being\n                              resized then the Condition will be set to 'Resizing'.\n                            items:\n                              description: PersistentVolumeClaimCondition contains details about state of pvc\n                              properties:\n                                lastProbeTime:\n                                  description: lastProbeTime is the time we probed the condition.\n                                  format: date-time\n                                  type: string\n                                lastTransitionTime:\n                                  description: lastTransitionTime is the time the condition transitioned from one status to another.\n                                  format: date-time\n                                  type: string\n                                message:\n                                  description: message is the human-readable message indicating details about last transition.\n                                  type: string\n                                reason:\n                                  description: |-\n                                    reason is a unique, this should be a short, machine understandable string that gives the reason\n                                    for condition's last transition. If it reports \"Resizing\" that means the underlying\n                                    persistent volume is being resized.\n                                  type: string\n                                status:\n                                  description: |-\n                                    Status is the status of the condition.\n                                    Can be True, False, Unknown.\n                                    More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=state%20of%20pvc-,conditions.status,-(string)%2C%20required\n                                  type: string\n                                type:\n                                  description: |-\n                                    Type is the type of the condition.\n                                    More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=set%20to%20%27ResizeStarted%27.-,PersistentVolumeClaimCondition,-contains%20details%20about\n                                  type: string\n                              required:\n                              - status\n                              - type\n                              type: object\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - type\n                            x-kubernetes-list-type: map\n                          currentVolumeAttributesClassName:\n                            description: |-\n                              currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using.\n                              When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim\n                              This is a beta field and requires enabling VolumeAttributesClass feature (off by default).\n                            type: string\n                          modifyVolumeStatus:\n                            description: |-\n                              ModifyVolumeStatus represents the status object of ControllerModifyVolume operation.\n                              When this is unset, there is no ModifyVolume operation being attempted.\n                              This is a beta field and requires enabling VolumeAttributesClass feature (off by default).\n                            properties:\n                              status:\n                                description: \"status is the status of the ControllerModifyVolume operation. It can be in any of following states:\\n - Pending\\n   Pending indicates that the PersistentVolumeClaim cannot be modified due to unmet requirements, such as\\n   the specified VolumeAttributesClass not existing.\\n - InProgress\\n   InProgress indicates that the volume is being modified.\\n - Infeasible\\n  Infeasible indicates that the request has been rejected as invalid by the CSI driver. To\\n\\t  resolve the error, a valid VolumeAttributesClass needs to be specified.\\nNote: New statuses can be added in the future. Consumers should check for unknown statuses and fail appropriately.\"\n                                type: string\n                              targetVolumeAttributesClassName:\n                                description: targetVolumeAttributesClassName is the name of the VolumeAttributesClass the PVC currently being reconciled\n                                type: string\n                            required:\n                            - status\n                            type: object\n                          phase:\n                            description: phase represents the current phase of PersistentVolumeClaim.\n                            type: string\n                        type: object\n                    type: object\n                type: object\n              tag:\n                description: |-\n                  Tag of Alertmanager container image to be deployed. Defaults to the value of `version`.\n                  Version is ignored if Tag is set.\n                  Deprecated: use 'image' instead. The image tag can be specified as part of the image URL.\n                type: string\n              terminationGracePeriodSeconds:\n                description: |-\n                  Optional duration in seconds the pod needs to terminate gracefully.\n                  Value must be non-negative integer. The value zero indicates stop immediately via\n                  the kill signal (no opportunity to shut down) which may lead to data corruption.\n\n                  Defaults to 120 seconds.\n                format: int64\n                minimum: 0\n                type: integer\n              tolerations:\n                description: If specified, the pod's tolerations.\n                items:\n                  description: |-\n                    The pod this Toleration is attached to tolerates any taint that matches\n                    the triple <key,value,effect> using the matching operator <operator>.\n                  properties:\n                    effect:\n                      description: |-\n                        Effect indicates the taint effect to match. Empty means match all taint effects.\n                        When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.\n                      type: string\n                    key:\n                      description: |-\n                        Key is the taint key that the toleration applies to. Empty means match all taint keys.\n                        If the key is empty, operator must be Exists; this combination means to match all values and all keys.\n                      type: string\n                    operator:\n                      description: |-\n                        Operator represents a key's relationship to the value.\n                        Valid operators are Exists and Equal. Defaults to Equal.\n                        Exists is equivalent to wildcard for value, so that a pod can\n                        tolerate all taints of a particular category.\n                      type: string\n                    tolerationSeconds:\n                      description: |-\n                        TolerationSeconds represents the period of time the toleration (which must be\n                        of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,\n                        it is not set, which means tolerate the taint forever (do not evict). Zero and\n                        negative values will be treated as 0 (evict immediately) by the system.\n                      format: int64\n                      type: integer\n                    value:\n                      description: |-\n                        Value is the taint value the toleration matches to.\n                        If the operator is Exists, the value should be empty, otherwise just a regular string.\n                      type: string\n                  type: object\n                type: array\n              topologySpreadConstraints:\n                description: If specified, the pod's topology spread constraints.\n                items:\n                  description: TopologySpreadConstraint specifies how to spread matching pods among the given topology.\n                  properties:\n                    labelSelector:\n                      description: |-\n                        LabelSelector is used to find matching pods.\n                        Pods that match this label selector are counted to determine the number of pods\n                        in their corresponding topology domain.\n                      properties:\n                        matchExpressions:\n                          description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                          items:\n                            description: |-\n                              A label selector requirement is a selector that contains values, a key, and an operator that\n                              relates the key and values.\n                            properties:\n                              key:\n                                description: key is the label key that the selector applies to.\n                                type: string\n                              operator:\n                                description: |-\n                                  operator represents a key's relationship to a set of values.\n                                  Valid operators are In, NotIn, Exists and DoesNotExist.\n                                type: string\n                              values:\n                                description: |-\n                                  values is an array of string values. If the operator is In or NotIn,\n                                  the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                  the values array must be empty. This array is replaced during a strategic\n                                  merge patch.\n                                items:\n                                  type: string\n                                type: array\n                                x-kubernetes-list-type: atomic\n                            required:\n                            - key\n                            - operator\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        matchLabels:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                            map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                            operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                          type: object\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    matchLabelKeys:\n                      description: |-\n                        MatchLabelKeys is a set of pod label keys to select the pods over which\n                        spreading will be calculated. The keys are used to lookup values from the\n                        incoming pod labels, those key-value labels are ANDed with labelSelector\n                        to select the group of existing pods over which spreading will be calculated\n                        for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.\n                        MatchLabelKeys cannot be set when LabelSelector isn't set.\n                        Keys that don't exist in the incoming pod labels will\n                        be ignored. A null or empty list means only match against labelSelector.\n\n                        This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default).\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    maxSkew:\n                      description: |-\n                        MaxSkew describes the degree to which pods may be unevenly distributed.\n                        When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference\n                        between the number of matching pods in the target topology and the global minimum.\n                        The global minimum is the minimum number of matching pods in an eligible domain\n                        or zero if the number of eligible domains is less than MinDomains.\n                        For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same\n                        labelSelector spread as 2/2/1:\n                        In this case, the global minimum is 1.\n                        | zone1 | zone2 | zone3 |\n                        |  P P  |  P P  |   P   |\n                        - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2;\n                        scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2)\n                        violate MaxSkew(1).\n                        - if MaxSkew is 2, incoming pod can be scheduled onto any zone.\n                        When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence\n                        to topologies that satisfy it.\n                        It's a required field. Default value is 1 and 0 is not allowed.\n                      format: int32\n                      type: integer\n                    minDomains:\n                      description: |-\n                        MinDomains indicates a minimum number of eligible domains.\n                        When the number of eligible domains with matching topology keys is less than minDomains,\n                        Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed.\n                        And when the number of eligible domains with matching topology keys equals or greater than minDomains,\n                        this value has no effect on scheduling.\n                        As a result, when the number of eligible domains is less than minDomains,\n                        scheduler won't schedule more than maxSkew Pods to those domains.\n                        If value is nil, the constraint behaves as if MinDomains is equal to 1.\n                        Valid values are integers greater than 0.\n                        When value is not nil, WhenUnsatisfiable must be DoNotSchedule.\n\n                        For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same\n                        labelSelector spread as 2/2/2:\n                        | zone1 | zone2 | zone3 |\n                        |  P P  |  P P  |  P P  |\n                        The number of domains is less than 5(MinDomains), so \"global minimum\" is treated as 0.\n                        In this situation, new pod with the same labelSelector cannot be scheduled,\n                        because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones,\n                        it will violate MaxSkew.\n                      format: int32\n                      type: integer\n                    nodeAffinityPolicy:\n                      description: |-\n                        NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector\n                        when calculating pod topology spread skew. Options are:\n                        - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations.\n                        - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.\n\n                        If this value is nil, the behavior is equivalent to the Honor policy.\n                      type: string\n                    nodeTaintsPolicy:\n                      description: |-\n                        NodeTaintsPolicy indicates how we will treat node taints when calculating\n                        pod topology spread skew. Options are:\n                        - Honor: nodes without taints, along with tainted nodes for which the incoming pod\n                        has a toleration, are included.\n                        - Ignore: node taints are ignored. All nodes are included.\n\n                        If this value is nil, the behavior is equivalent to the Ignore policy.\n                      type: string\n                    topologyKey:\n                      description: |-\n                        TopologyKey is the key of node labels. Nodes that have a label with this key\n                        and identical values are considered to be in the same topology.\n                        We consider each <key, value> as a \"bucket\", and try to put balanced number\n                        of pods into each bucket.\n                        We define a domain as a particular instance of a topology.\n                        Also, we define an eligible domain as a domain whose nodes meet the requirements of\n                        nodeAffinityPolicy and nodeTaintsPolicy.\n                        e.g. If TopologyKey is \"kubernetes.io/hostname\", each Node is a domain of that topology.\n                        And, if TopologyKey is \"topology.kubernetes.io/zone\", each zone is a domain of that topology.\n                        It's a required field.\n                      type: string\n                    whenUnsatisfiable:\n                      description: |-\n                        WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy\n                        the spread constraint.\n                        - DoNotSchedule (default) tells the scheduler not to schedule it.\n                        - ScheduleAnyway tells the scheduler to schedule the pod in any location,\n                          but giving higher precedence to topologies that would help reduce the\n                          skew.\n                        A constraint is considered \"Unsatisfiable\" for an incoming pod\n                        if and only if every possible node assignment for that pod would violate\n                        \"MaxSkew\" on some topology.\n                        For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same\n                        labelSelector spread as 3/1/1:\n                        | zone1 | zone2 | zone3 |\n                        | P P P |   P   |   P   |\n                        If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled\n                        to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies\n                        MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler\n                        won't make it *more* imbalanced.\n                        It's a required field.\n                      type: string\n                  required:\n                  - maxSkew\n                  - topologyKey\n                  - whenUnsatisfiable\n                  type: object\n                type: array\n              version:\n                description: Version the cluster should be on.\n                type: string\n              volumeMounts:\n                description: |-\n                  VolumeMounts allows configuration of additional VolumeMounts on the output StatefulSet definition.\n                  VolumeMounts specified will be appended to other VolumeMounts in the alertmanager container,\n                  that are generated as a result of StorageSpec objects.\n                items:\n                  description: VolumeMount describes a mounting of a Volume within a container.\n                  properties:\n                    mountPath:\n                      description: |-\n                        Path within the container at which the volume should be mounted.  Must\n                        not contain ':'.\n                      type: string\n                    mountPropagation:\n                      description: |-\n                        mountPropagation determines how mounts are propagated from the host\n                        to container and the other way around.\n                        When not set, MountPropagationNone is used.\n                        This field is beta in 1.10.\n                        When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                        (which defaults to None).\n                      type: string\n                    name:\n                      description: This must match the Name of a Volume.\n                      type: string\n                    readOnly:\n                      description: |-\n                        Mounted read-only if true, read-write otherwise (false or unspecified).\n                        Defaults to false.\n                      type: boolean\n                    recursiveReadOnly:\n                      description: |-\n                        RecursiveReadOnly specifies whether read-only mounts should be handled\n                        recursively.\n\n                        If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                        If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                        recursively read-only.  If this field is set to IfPossible, the mount is made\n                        recursively read-only, if it is supported by the container runtime.  If this\n                        field is set to Enabled, the mount is made recursively read-only if it is\n                        supported by the container runtime, otherwise the pod will not be started and\n                        an error will be generated to indicate the reason.\n\n                        If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                        None (or be unspecified, which defaults to None).\n\n                        If this field is not specified, it is treated as an equivalent of Disabled.\n                      type: string\n                    subPath:\n                      description: |-\n                        Path within the volume from which the container's volume should be mounted.\n                        Defaults to \"\" (volume's root).\n                      type: string\n                    subPathExpr:\n                      description: |-\n                        Expanded path within the volume from which the container's volume should be mounted.\n                        Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                        Defaults to \"\" (volume's root).\n                        SubPathExpr and SubPath are mutually exclusive.\n                      type: string\n                  required:\n                  - mountPath\n                  - name\n                  type: object\n                type: array\n              volumes:\n                description: |-\n                  Volumes allows configuration of additional volumes on the output StatefulSet definition.\n                  Volumes specified will be appended to other volumes that are generated as a result of\n                  StorageSpec objects.\n                items:\n                  description: Volume represents a named volume in a pod that may be accessed by any container in the pod.\n                  properties:\n                    awsElasticBlockStore:\n                      description: |-\n                        awsElasticBlockStore represents an AWS Disk resource that is attached to a\n                        kubelet's host machine and then exposed to the pod.\n                        Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree\n                        awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                          type: string\n                        partition:\n                          description: |-\n                            partition is the partition in the volume that you want to mount.\n                            If omitted, the default is to mount by volume name.\n                            Examples: For volume /dev/sda1, you specify the partition as \"1\".\n                            Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty).\n                          format: int32\n                          type: integer\n                        readOnly:\n                          description: |-\n                            readOnly value true will force the readOnly setting in VolumeMounts.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                          type: boolean\n                        volumeID:\n                          description: |-\n                            volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume).\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                          type: string\n                      required:\n                      - volumeID\n                      type: object\n                    azureDisk:\n                      description: |-\n                        azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.\n                        Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type\n                        are redirected to the disk.csi.azure.com CSI driver.\n                      properties:\n                        cachingMode:\n                          description: 'cachingMode is the Host Caching mode: None, Read Only, Read Write.'\n                          type: string\n                        diskName:\n                          description: diskName is the Name of the data disk in the blob storage\n                          type: string\n                        diskURI:\n                          description: diskURI is the URI of data disk in the blob storage\n                          type: string\n                        fsType:\n                          default: ext4\n                          description: |-\n                            fsType is Filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        kind:\n                          description: 'kind expected values are Shared: multiple blob disks per storage account  Dedicated: single blob disk per storage account  Managed: azure managed data disk (only in managed availability set). defaults to shared'\n                          type: string\n                        readOnly:\n                          default: false\n                          description: |-\n                            readOnly Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                      required:\n                      - diskName\n                      - diskURI\n                      type: object\n                    azureFile:\n                      description: |-\n                        azureFile represents an Azure File Service mount on the host and bind mount to the pod.\n                        Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type\n                        are redirected to the file.csi.azure.com CSI driver.\n                      properties:\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretName:\n                          description: secretName is the  name of secret that contains Azure Storage Account Name and Key\n                          type: string\n                        shareName:\n                          description: shareName is the azure share Name\n                          type: string\n                      required:\n                      - secretName\n                      - shareName\n                      type: object\n                    cephfs:\n                      description: |-\n                        cephFS represents a Ceph FS mount on the host that shares a pod's lifetime.\n                        Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported.\n                      properties:\n                        monitors:\n                          description: |-\n                            monitors is Required: Monitors is a collection of Ceph monitors\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        path:\n                          description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /'\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly is Optional: Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          type: boolean\n                        secretFile:\n                          description: |-\n                            secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          type: string\n                        secretRef:\n                          description: |-\n                            secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty.\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        user:\n                          description: |-\n                            user is optional: User is the rados user name, default is admin\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          type: string\n                      required:\n                      - monitors\n                      type: object\n                    cinder:\n                      description: |-\n                        cinder represents a cinder volume attached and mounted on kubelets host machine.\n                        Deprecated: Cinder is deprecated. All operations for the in-tree cinder type\n                        are redirected to the cinder.csi.openstack.org CSI driver.\n                        More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                            More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef is optional: points to a secret object containing parameters used to connect\n                            to OpenStack.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        volumeID:\n                          description: |-\n                            volumeID used to identify the volume in cinder.\n                            More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                          type: string\n                      required:\n                      - volumeID\n                      type: object\n                    configMap:\n                      description: configMap represents a configMap that should populate this volume\n                      properties:\n                        defaultMode:\n                          description: |-\n                            defaultMode is optional: mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                            Defaults to 0644.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        items:\n                          description: |-\n                            items if unspecified, each key-value pair in the Data field of the referenced\n                            ConfigMap will be projected into the volume as a file whose name is the\n                            key and content is the value. If specified, the listed keys will be\n                            projected into the specified paths, and unlisted keys will not be\n                            present. If a key is specified which is not present in the ConfigMap,\n                            the volume setup will error unless it is marked optional. Paths must be\n                            relative and may not contain the '..' path or start with '..'.\n                          items:\n                            description: Maps a string key to a path within a volume.\n                            properties:\n                              key:\n                                description: key is the key to project.\n                                type: string\n                              mode:\n                                description: |-\n                                  mode is Optional: mode bits used to set permissions on this file.\n                                  Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                  YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                  If not specified, the volume defaultMode will be used.\n                                  This might be in conflict with other options that affect the file\n                                  mode, like fsGroup, and the result can be other mode bits set.\n                                format: int32\n                                type: integer\n                              path:\n                                description: |-\n                                  path is the relative path of the file to map the key to.\n                                  May not be an absolute path.\n                                  May not contain the path element '..'.\n                                  May not start with the string '..'.\n                                type: string\n                            required:\n                            - key\n                            - path\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: optional specify whether the ConfigMap or its keys must be defined\n                          type: boolean\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    csi:\n                      description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers.\n                      properties:\n                        driver:\n                          description: |-\n                            driver is the name of the CSI driver that handles this volume.\n                            Consult with your admin for the correct name as registered in the cluster.\n                          type: string\n                        fsType:\n                          description: |-\n                            fsType to mount. Ex. \"ext4\", \"xfs\", \"ntfs\".\n                            If not provided, the empty value is passed to the associated CSI driver\n                            which will determine the default filesystem to apply.\n                          type: string\n                        nodePublishSecretRef:\n                          description: |-\n                            nodePublishSecretRef is a reference to the secret object containing\n                            sensitive information to pass to the CSI driver to complete the CSI\n                            NodePublishVolume and NodeUnpublishVolume calls.\n                            This field is optional, and  may be empty if no secret is required. If the\n                            secret object contains more than one secret, all secret references are passed.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        readOnly:\n                          description: |-\n                            readOnly specifies a read-only configuration for the volume.\n                            Defaults to false (read/write).\n                          type: boolean\n                        volumeAttributes:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            volumeAttributes stores driver-specific properties that are passed to the CSI\n                            driver. Consult your driver's documentation for supported values.\n                          type: object\n                      required:\n                      - driver\n                      type: object\n                    downwardAPI:\n                      description: downwardAPI represents downward API about the pod that should populate this volume\n                      properties:\n                        defaultMode:\n                          description: |-\n                            Optional: mode bits to use on created files by default. Must be a\n                            Optional: mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                            Defaults to 0644.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        items:\n                          description: Items is a list of downward API volume file\n                          items:\n                            description: DownwardAPIVolumeFile represents information to create the file containing the pod field\n                            properties:\n                              fieldRef:\n                                description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.'\n                                properties:\n                                  apiVersion:\n                                    description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                    type: string\n                                  fieldPath:\n                                    description: Path of the field to select in the specified API version.\n                                    type: string\n                                required:\n                                - fieldPath\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              mode:\n                                description: |-\n                                  Optional: mode bits used to set permissions on this file, must be an octal value\n                                  between 0000 and 0777 or a decimal value between 0 and 511.\n                                  YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                  If not specified, the volume defaultMode will be used.\n                                  This might be in conflict with other options that affect the file\n                                  mode, like fsGroup, and the result can be other mode bits set.\n                                format: int32\n                                type: integer\n                              path:\n                                description: 'Required: Path is  the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..'''\n                                type: string\n                              resourceFieldRef:\n                                description: |-\n                                  Selects a resource of the container: only resources limits and requests\n                                  (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.\n                                properties:\n                                  containerName:\n                                    description: 'Container name: required for volumes, optional for env vars'\n                                    type: string\n                                  divisor:\n                                    anyOf:\n                                    - type: integer\n                                    - type: string\n                                    description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                    x-kubernetes-int-or-string: true\n                                  resource:\n                                    description: 'Required: resource to select'\n                                    type: string\n                                required:\n                                - resource\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            required:\n                            - path\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    emptyDir:\n                      description: |-\n                        emptyDir represents a temporary directory that shares a pod's lifetime.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                      properties:\n                        medium:\n                          description: |-\n                            medium represents what type of storage medium should back this directory.\n                            The default is \"\" which means to use the node's default medium.\n                            Must be an empty string (default) or Memory.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                          type: string\n                        sizeLimit:\n                          anyOf:\n                          - type: integer\n                          - type: string\n                          description: |-\n                            sizeLimit is the total amount of local storage required for this EmptyDir volume.\n                            The size limit is also applicable for memory medium.\n                            The maximum usage on memory medium EmptyDir would be the minimum value between\n                            the SizeLimit specified here and the sum of memory limits of all containers in a pod.\n                            The default is nil which means that the limit is undefined.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                          pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                          x-kubernetes-int-or-string: true\n                      type: object\n                    ephemeral:\n                      description: |-\n                        ephemeral represents a volume that is handled by a cluster storage driver.\n                        The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts,\n                        and deleted when the pod is removed.\n\n                        Use this if:\n                        a) the volume is only needed while the pod runs,\n                        b) features of normal volumes like restoring from snapshot or capacity\n                           tracking are needed,\n                        c) the storage driver is specified through a storage class, and\n                        d) the storage driver supports dynamic volume provisioning through\n                           a PersistentVolumeClaim (see EphemeralVolumeSource for more\n                           information on the connection between this volume type\n                           and PersistentVolumeClaim).\n\n                        Use PersistentVolumeClaim or one of the vendor-specific\n                        APIs for volumes that persist for longer than the lifecycle\n                        of an individual pod.\n\n                        Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to\n                        be used that way - see the documentation of the driver for\n                        more information.\n\n                        A pod can use both types of ephemeral volumes and\n                        persistent volumes at the same time.\n                      properties:\n                        volumeClaimTemplate:\n                          description: |-\n                            Will be used to create a stand-alone PVC to provision the volume.\n                            The pod in which this EphemeralVolumeSource is embedded will be the\n                            owner of the PVC, i.e. the PVC will be deleted together with the\n                            pod.  The name of the PVC will be `<pod name>-<volume name>` where\n                            `<volume name>` is the name from the `PodSpec.Volumes` array\n                            entry. Pod validation will reject the pod if the concatenated name\n                            is not valid for a PVC (for example, too long).\n\n                            An existing PVC with that name that is not owned by the pod\n                            will *not* be used for the pod to avoid using an unrelated\n                            volume by mistake. Starting the pod is then blocked until\n                            the unrelated PVC is removed. If such a pre-created PVC is\n                            meant to be used by the pod, the PVC has to updated with an\n                            owner reference to the pod once the pod exists. Normally\n                            this should not be necessary, but it may be useful when\n                            manually reconstructing a broken cluster.\n\n                            This field is read-only and no changes will be made by Kubernetes\n                            to the PVC after it has been created.\n\n                            Required, must not be nil.\n                          properties:\n                            metadata:\n                              description: |-\n                                May contain labels and annotations that will be copied into the PVC\n                                when creating it. No other fields are allowed and will be rejected during\n                                validation.\n                              type: object\n                            spec:\n                              description: |-\n                                The specification for the PersistentVolumeClaim. The entire content is\n                                copied unchanged into the PVC that gets created from this\n                                template. The same fields as in a PersistentVolumeClaim\n                                are also valid here.\n                              properties:\n                                accessModes:\n                                  description: |-\n                                    accessModes contains the desired access modes the volume should have.\n                                    More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                dataSource:\n                                  description: |-\n                                    dataSource field can be used to specify either:\n                                    * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n                                    * An existing PVC (PersistentVolumeClaim)\n                                    If the provisioner or an external controller can support the specified data source,\n                                    it will create a new volume based on the contents of the specified data source.\n                                    When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\n                                    and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\n                                    If the namespace is specified, then dataSourceRef will not be copied to dataSource.\n                                  properties:\n                                    apiGroup:\n                                      description: |-\n                                        APIGroup is the group for the resource being referenced.\n                                        If APIGroup is not specified, the specified Kind must be in the core API group.\n                                        For any other third-party types, APIGroup is required.\n                                      type: string\n                                    kind:\n                                      description: Kind is the type of resource being referenced\n                                      type: string\n                                    name:\n                                      description: Name is the name of resource being referenced\n                                      type: string\n                                  required:\n                                  - kind\n                                  - name\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                dataSourceRef:\n                                  description: |-\n                                    dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\n                                    volume is desired. This may be any object from a non-empty API group (non\n                                    core object) or a PersistentVolumeClaim object.\n                                    When this field is specified, volume binding will only succeed if the type of\n                                    the specified object matches some installed volume populator or dynamic\n                                    provisioner.\n                                    This field will replace the functionality of the dataSource field and as such\n                                    if both fields are non-empty, they must have the same value. For backwards\n                                    compatibility, when namespace isn't specified in dataSourceRef,\n                                    both fields (dataSource and dataSourceRef) will be set to the same\n                                    value automatically if one of them is empty and the other is non-empty.\n                                    When namespace is specified in dataSourceRef,\n                                    dataSource isn't set to the same value and must be empty.\n                                    There are three important differences between dataSource and dataSourceRef:\n                                    * While dataSource only allows two specific types of objects, dataSourceRef\n                                      allows any non-core object, as well as PersistentVolumeClaim objects.\n                                    * While dataSource ignores disallowed values (dropping them), dataSourceRef\n                                      preserves all values, and generates an error if a disallowed value is\n                                      specified.\n                                    * While dataSource only allows local objects, dataSourceRef allows objects\n                                      in any namespaces.\n                                    (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n                                    (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                  properties:\n                                    apiGroup:\n                                      description: |-\n                                        APIGroup is the group for the resource being referenced.\n                                        If APIGroup is not specified, the specified Kind must be in the core API group.\n                                        For any other third-party types, APIGroup is required.\n                                      type: string\n                                    kind:\n                                      description: Kind is the type of resource being referenced\n                                      type: string\n                                    name:\n                                      description: Name is the name of resource being referenced\n                                      type: string\n                                    namespace:\n                                      description: |-\n                                        Namespace is the namespace of resource being referenced\n                                        Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n                                        (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                      type: string\n                                  required:\n                                  - kind\n                                  - name\n                                  type: object\n                                resources:\n                                  description: |-\n                                    resources represents the minimum resources the volume should have.\n                                    If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\n                                    that are lower than previous value but must still be higher than capacity recorded in the\n                                    status field of the claim.\n                                    More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources\n                                  properties:\n                                    limits:\n                                      additionalProperties:\n                                        anyOf:\n                                        - type: integer\n                                        - type: string\n                                        pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                        x-kubernetes-int-or-string: true\n                                      description: |-\n                                        Limits describes the maximum amount of compute resources allowed.\n                                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                      type: object\n                                    requests:\n                                      additionalProperties:\n                                        anyOf:\n                                        - type: integer\n                                        - type: string\n                                        pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                        x-kubernetes-int-or-string: true\n                                      description: |-\n                                        Requests describes the minimum amount of compute resources required.\n                                        If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                                        otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                      type: object\n                                  type: object\n                                selector:\n                                  description: selector is a label query over volumes to consider for binding.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                storageClassName:\n                                  description: |-\n                                    storageClassName is the name of the StorageClass required by the claim.\n                                    More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1\n                                  type: string\n                                volumeAttributesClassName:\n                                  description: |-\n                                    volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\n                                    If specified, the CSI driver will create or update the volume with the attributes defined\n                                    in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\n                                    it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\n                                    will be applied to the claim but it's not allowed to reset this field to empty string once it is set.\n                                    If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\n                                    will be set by the persistentvolume controller if it exists.\n                                    If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\n                                    set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\n                                    exists.\n                                    More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n                                    (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).\n                                  type: string\n                                volumeMode:\n                                  description: |-\n                                    volumeMode defines what type of volume is required by the claim.\n                                    Value of Filesystem is implied when not included in claim spec.\n                                  type: string\n                                volumeName:\n                                  description: volumeName is the binding reference to the PersistentVolume backing this claim.\n                                  type: string\n                              type: object\n                          required:\n                          - spec\n                          type: object\n                      type: object\n                    fc:\n                      description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        lun:\n                          description: 'lun is Optional: FC target lun number'\n                          format: int32\n                          type: integer\n                        readOnly:\n                          description: |-\n                            readOnly is Optional: Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        targetWWNs:\n                          description: 'targetWWNs is Optional: FC target worldwide names (WWNs)'\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        wwids:\n                          description: |-\n                            wwids Optional: FC volume world wide identifiers (wwids)\n                            Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    flexVolume:\n                      description: |-\n                        flexVolume represents a generic volume resource that is\n                        provisioned/attached using an exec based plugin.\n                        Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead.\n                      properties:\n                        driver:\n                          description: driver is the name of the driver to use for this volume.\n                          type: string\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". The default filesystem depends on FlexVolume script.\n                          type: string\n                        options:\n                          additionalProperties:\n                            type: string\n                          description: 'options is Optional: this field holds extra command options if any.'\n                          type: object\n                        readOnly:\n                          description: |-\n                            readOnly is Optional: defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef is Optional: secretRef is reference to the secret object containing\n                            sensitive information to pass to the plugin scripts. This may be\n                            empty if no secret object is specified. If the secret object\n                            contains more than one secret, all secrets are passed to the plugin\n                            scripts.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      required:\n                      - driver\n                      type: object\n                    flocker:\n                      description: |-\n                        flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running.\n                        Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported.\n                      properties:\n                        datasetName:\n                          description: |-\n                            datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker\n                            should be considered as deprecated\n                          type: string\n                        datasetUUID:\n                          description: datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset\n                          type: string\n                      type: object\n                    gcePersistentDisk:\n                      description: |-\n                        gcePersistentDisk represents a GCE Disk resource that is attached to a\n                        kubelet's host machine and then exposed to the pod.\n                        Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree\n                        gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          type: string\n                        partition:\n                          description: |-\n                            partition is the partition in the volume that you want to mount.\n                            If omitted, the default is to mount by volume name.\n                            Examples: For volume /dev/sda1, you specify the partition as \"1\".\n                            Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty).\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          format: int32\n                          type: integer\n                        pdName:\n                          description: |-\n                            pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the ReadOnly setting in VolumeMounts.\n                            Defaults to false.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          type: boolean\n                      required:\n                      - pdName\n                      type: object\n                    gitRepo:\n                      description: |-\n                        gitRepo represents a git repository at a particular revision.\n                        Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an\n                        EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir\n                        into the Pod's container.\n                      properties:\n                        directory:\n                          description: |-\n                            directory is the target directory name.\n                            Must not contain or start with '..'.  If '.' is supplied, the volume directory will be the\n                            git repository.  Otherwise, if specified, the volume will contain the git repository in\n                            the subdirectory with the given name.\n                          type: string\n                        repository:\n                          description: repository is the URL\n                          type: string\n                        revision:\n                          description: revision is the commit hash for the specified revision.\n                          type: string\n                      required:\n                      - repository\n                      type: object\n                    glusterfs:\n                      description: |-\n                        glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime.\n                        Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported.\n                        More info: https://examples.k8s.io/volumes/glusterfs/README.md\n                      properties:\n                        endpoints:\n                          description: |-\n                            endpoints is the endpoint name that details Glusterfs topology.\n                            More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod\n                          type: string\n                        path:\n                          description: |-\n                            path is the Glusterfs volume path.\n                            More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the Glusterfs volume to be mounted with read-only permissions.\n                            Defaults to false.\n                            More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod\n                          type: boolean\n                      required:\n                      - endpoints\n                      - path\n                      type: object\n                    hostPath:\n                      description: |-\n                        hostPath represents a pre-existing file or directory on the host\n                        machine that is directly exposed to the container. This is generally\n                        used for system agents or other privileged things that are allowed\n                        to see the host machine. Most containers will NOT need this.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath\n                      properties:\n                        path:\n                          description: |-\n                            path of the directory on the host.\n                            If the path is a symlink, it will follow the link to the real path.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath\n                          type: string\n                        type:\n                          description: |-\n                            type for HostPath Volume\n                            Defaults to \"\"\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath\n                          type: string\n                      required:\n                      - path\n                      type: object\n                    image:\n                      description: |-\n                        image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine.\n                        The volume is resolved at pod startup depending on which PullPolicy value is provided:\n\n                        - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails.\n                        - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.\n                        - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n\n                        The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation.\n                        A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message.\n                        The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field.\n                        The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images.\n                        The volume will be mounted read-only (ro) and non-executable files (noexec).\n                        Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33.\n                        The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.\n                      properties:\n                        pullPolicy:\n                          description: |-\n                            Policy for pulling OCI objects. Possible values are:\n                            Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails.\n                            Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.\n                            IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n                            Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.\n                          type: string\n                        reference:\n                          description: |-\n                            Required: Image or artifact reference to be used.\n                            Behaves in the same way as pod.spec.containers[*].image.\n                            Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets.\n                            More info: https://kubernetes.io/docs/concepts/containers/images\n                            This field is optional to allow higher level config management to default or override\n                            container images in workload controllers like Deployments and StatefulSets.\n                          type: string\n                      type: object\n                    iscsi:\n                      description: |-\n                        iscsi represents an ISCSI Disk resource that is attached to a\n                        kubelet's host machine and then exposed to the pod.\n                        More info: https://examples.k8s.io/volumes/iscsi/README.md\n                      properties:\n                        chapAuthDiscovery:\n                          description: chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication\n                          type: boolean\n                        chapAuthSession:\n                          description: chapAuthSession defines whether support iSCSI Session CHAP authentication\n                          type: boolean\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi\n                          type: string\n                        initiatorName:\n                          description: |-\n                            initiatorName is the custom iSCSI Initiator Name.\n                            If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface\n                            <target portal>:<volume name> will be created for the connection.\n                          type: string\n                        iqn:\n                          description: iqn is the target iSCSI Qualified Name.\n                          type: string\n                        iscsiInterface:\n                          default: default\n                          description: |-\n                            iscsiInterface is the interface Name that uses an iSCSI transport.\n                            Defaults to 'default' (tcp).\n                          type: string\n                        lun:\n                          description: lun represents iSCSI Target Lun number.\n                          format: int32\n                          type: integer\n                        portals:\n                          description: |-\n                            portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port\n                            is other than default (typically TCP ports 860 and 3260).\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        readOnly:\n                          description: |-\n                            readOnly here will force the ReadOnly setting in VolumeMounts.\n                            Defaults to false.\n                          type: boolean\n                        secretRef:\n                          description: secretRef is the CHAP Secret for iSCSI target and initiator authentication\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        targetPortal:\n                          description: |-\n                            targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port\n                            is other than default (typically TCP ports 860 and 3260).\n                          type: string\n                      required:\n                      - iqn\n                      - lun\n                      - targetPortal\n                      type: object\n                    name:\n                      description: |-\n                        name of the volume.\n                        Must be a DNS_LABEL and unique within the pod.\n                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                      type: string\n                    nfs:\n                      description: |-\n                        nfs represents an NFS mount on the host that shares a pod's lifetime\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                      properties:\n                        path:\n                          description: |-\n                            path that is exported by the NFS server.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the NFS export to be mounted with read-only permissions.\n                            Defaults to false.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                          type: boolean\n                        server:\n                          description: |-\n                            server is the hostname or IP address of the NFS server.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                          type: string\n                      required:\n                      - path\n                      - server\n                      type: object\n                    persistentVolumeClaim:\n                      description: |-\n                        persistentVolumeClaimVolumeSource represents a reference to a\n                        PersistentVolumeClaim in the same namespace.\n                        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims\n                      properties:\n                        claimName:\n                          description: |-\n                            claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume.\n                            More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly Will force the ReadOnly setting in VolumeMounts.\n                            Default false.\n                          type: boolean\n                      required:\n                      - claimName\n                      type: object\n                    photonPersistentDisk:\n                      description: |-\n                        photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine.\n                        Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        pdID:\n                          description: pdID is the ID that identifies Photon Controller persistent disk\n                          type: string\n                      required:\n                      - pdID\n                      type: object\n                    portworxVolume:\n                      description: |-\n                        portworxVolume represents a portworx volume attached and mounted on kubelets host machine.\n                        Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type\n                        are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate\n                        is on.\n                      properties:\n                        fsType:\n                          description: |-\n                            fSType represents the filesystem type to mount\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        volumeID:\n                          description: volumeID uniquely identifies a Portworx volume\n                          type: string\n                      required:\n                      - volumeID\n                      type: object\n                    projected:\n                      description: projected items for all in one resources secrets, configmaps, and downward API\n                      properties:\n                        defaultMode:\n                          description: |-\n                            defaultMode are the mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        sources:\n                          description: |-\n                            sources is the list of volume projections. Each entry in this list\n                            handles one source.\n                          items:\n                            description: |-\n                              Projection that may be projected along with other supported volume types.\n                              Exactly one of these fields must be set.\n                            properties:\n                              clusterTrustBundle:\n                                description: |-\n                                  ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field\n                                  of ClusterTrustBundle objects in an auto-updating file.\n\n                                  Alpha, gated by the ClusterTrustBundleProjection feature gate.\n\n                                  ClusterTrustBundle objects can either be selected by name, or by the\n                                  combination of signer name and a label selector.\n\n                                  Kubelet performs aggressive normalization of the PEM contents written\n                                  into the pod filesystem.  Esoteric PEM features such as inter-block\n                                  comments and block headers are stripped.  Certificates are deduplicated.\n                                  The ordering of certificates within the file is arbitrary, and Kubelet\n                                  may change the order over time.\n                                properties:\n                                  labelSelector:\n                                    description: |-\n                                      Select all ClusterTrustBundles that match this label selector.  Only has\n                                      effect if signerName is set.  Mutually-exclusive with name.  If unset,\n                                      interpreted as \"match nothing\".  If set but empty, interpreted as \"match\n                                      everything\".\n                                    properties:\n                                      matchExpressions:\n                                        description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                        items:\n                                          description: |-\n                                            A label selector requirement is a selector that contains values, a key, and an operator that\n                                            relates the key and values.\n                                          properties:\n                                            key:\n                                              description: key is the label key that the selector applies to.\n                                              type: string\n                                            operator:\n                                              description: |-\n                                                operator represents a key's relationship to a set of values.\n                                                Valid operators are In, NotIn, Exists and DoesNotExist.\n                                              type: string\n                                            values:\n                                              description: |-\n                                                values is an array of string values. If the operator is In or NotIn,\n                                                the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                                the values array must be empty. This array is replaced during a strategic\n                                                merge patch.\n                                              items:\n                                                type: string\n                                              type: array\n                                              x-kubernetes-list-type: atomic\n                                          required:\n                                          - key\n                                          - operator\n                                          type: object\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                      matchLabels:\n                                        additionalProperties:\n                                          type: string\n                                        description: |-\n                                          matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                          map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                          operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                        type: object\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  name:\n                                    description: |-\n                                      Select a single ClusterTrustBundle by object name.  Mutually-exclusive\n                                      with signerName and labelSelector.\n                                    type: string\n                                  optional:\n                                    description: |-\n                                      If true, don't block pod startup if the referenced ClusterTrustBundle(s)\n                                      aren't available.  If using name, then the named ClusterTrustBundle is\n                                      allowed not to exist.  If using signerName, then the combination of\n                                      signerName and labelSelector is allowed to match zero\n                                      ClusterTrustBundles.\n                                    type: boolean\n                                  path:\n                                    description: Relative path from the volume root to write the bundle.\n                                    type: string\n                                  signerName:\n                                    description: |-\n                                      Select all ClusterTrustBundles that match this signer name.\n                                      Mutually-exclusive with name.  The contents of all selected\n                                      ClusterTrustBundles will be unified and deduplicated.\n                                    type: string\n                                required:\n                                - path\n                                type: object\n                              configMap:\n                                description: configMap information about the configMap data to project\n                                properties:\n                                  items:\n                                    description: |-\n                                      items if unspecified, each key-value pair in the Data field of the referenced\n                                      ConfigMap will be projected into the volume as a file whose name is the\n                                      key and content is the value. If specified, the listed keys will be\n                                      projected into the specified paths, and unlisted keys will not be\n                                      present. If a key is specified which is not present in the ConfigMap,\n                                      the volume setup will error unless it is marked optional. Paths must be\n                                      relative and may not contain the '..' path or start with '..'.\n                                    items:\n                                      description: Maps a string key to a path within a volume.\n                                      properties:\n                                        key:\n                                          description: key is the key to project.\n                                          type: string\n                                        mode:\n                                          description: |-\n                                            mode is Optional: mode bits used to set permissions on this file.\n                                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                            If not specified, the volume defaultMode will be used.\n                                            This might be in conflict with other options that affect the file\n                                            mode, like fsGroup, and the result can be other mode bits set.\n                                          format: int32\n                                          type: integer\n                                        path:\n                                          description: |-\n                                            path is the relative path of the file to map the key to.\n                                            May not be an absolute path.\n                                            May not contain the path element '..'.\n                                            May not start with the string '..'.\n                                          type: string\n                                      required:\n                                      - key\n                                      - path\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: optional specify whether the ConfigMap or its keys must be defined\n                                    type: boolean\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              downwardAPI:\n                                description: downwardAPI information about the downwardAPI data to project\n                                properties:\n                                  items:\n                                    description: Items is a list of DownwardAPIVolume file\n                                    items:\n                                      description: DownwardAPIVolumeFile represents information to create the file containing the pod field\n                                      properties:\n                                        fieldRef:\n                                          description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.'\n                                          properties:\n                                            apiVersion:\n                                              description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                              type: string\n                                            fieldPath:\n                                              description: Path of the field to select in the specified API version.\n                                              type: string\n                                          required:\n                                          - fieldPath\n                                          type: object\n                                          x-kubernetes-map-type: atomic\n                                        mode:\n                                          description: |-\n                                            Optional: mode bits used to set permissions on this file, must be an octal value\n                                            between 0000 and 0777 or a decimal value between 0 and 511.\n                                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                            If not specified, the volume defaultMode will be used.\n                                            This might be in conflict with other options that affect the file\n                                            mode, like fsGroup, and the result can be other mode bits set.\n                                          format: int32\n                                          type: integer\n                                        path:\n                                          description: 'Required: Path is  the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..'''\n                                          type: string\n                                        resourceFieldRef:\n                                          description: |-\n                                            Selects a resource of the container: only resources limits and requests\n                                            (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.\n                                          properties:\n                                            containerName:\n                                              description: 'Container name: required for volumes, optional for env vars'\n                                              type: string\n                                            divisor:\n                                              anyOf:\n                                              - type: integer\n                                              - type: string\n                                              description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                              pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                              x-kubernetes-int-or-string: true\n                                            resource:\n                                              description: 'Required: resource to select'\n                                              type: string\n                                          required:\n                                          - resource\n                                          type: object\n                                          x-kubernetes-map-type: atomic\n                                      required:\n                                      - path\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                type: object\n                              secret:\n                                description: secret information about the secret data to project\n                                properties:\n                                  items:\n                                    description: |-\n                                      items if unspecified, each key-value pair in the Data field of the referenced\n                                      Secret will be projected into the volume as a file whose name is the\n                                      key and content is the value. If specified, the listed keys will be\n                                      projected into the specified paths, and unlisted keys will not be\n                                      present. If a key is specified which is not present in the Secret,\n                                      the volume setup will error unless it is marked optional. Paths must be\n                                      relative and may not contain the '..' path or start with '..'.\n                                    items:\n                                      description: Maps a string key to a path within a volume.\n                                      properties:\n                                        key:\n                                          description: key is the key to project.\n                                          type: string\n                                        mode:\n                                          description: |-\n                                            mode is Optional: mode bits used to set permissions on this file.\n                                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                            If not specified, the volume defaultMode will be used.\n                                            This might be in conflict with other options that affect the file\n                                            mode, like fsGroup, and the result can be other mode bits set.\n                                          format: int32\n                                          type: integer\n                                        path:\n                                          description: |-\n                                            path is the relative path of the file to map the key to.\n                                            May not be an absolute path.\n                                            May not contain the path element '..'.\n                                            May not start with the string '..'.\n                                          type: string\n                                      required:\n                                      - key\n                                      - path\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: optional field specify whether the Secret or its key must be defined\n                                    type: boolean\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              serviceAccountToken:\n                                description: serviceAccountToken is information about the serviceAccountToken data to project\n                                properties:\n                                  audience:\n                                    description: |-\n                                      audience is the intended audience of the token. A recipient of a token\n                                      must identify itself with an identifier specified in the audience of the\n                                      token, and otherwise should reject the token. The audience defaults to the\n                                      identifier of the apiserver.\n                                    type: string\n                                  expirationSeconds:\n                                    description: |-\n                                      expirationSeconds is the requested duration of validity of the service\n                                      account token. As the token approaches expiration, the kubelet volume\n                                      plugin will proactively rotate the service account token. The kubelet will\n                                      start trying to rotate the token if the token is older than 80 percent of\n                                      its time to live or if the token is older than 24 hours.Defaults to 1 hour\n                                      and must be at least 10 minutes.\n                                    format: int64\n                                    type: integer\n                                  path:\n                                    description: |-\n                                      path is the path relative to the mount point of the file to project the\n                                      token into.\n                                    type: string\n                                required:\n                                - path\n                                type: object\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    quobyte:\n                      description: |-\n                        quobyte represents a Quobyte mount on the host that shares a pod's lifetime.\n                        Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported.\n                      properties:\n                        group:\n                          description: |-\n                            group to map volume access to\n                            Default is no group\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the Quobyte volume to be mounted with read-only permissions.\n                            Defaults to false.\n                          type: boolean\n                        registry:\n                          description: |-\n                            registry represents a single or multiple Quobyte Registry services\n                            specified as a string as host:port pair (multiple entries are separated with commas)\n                            which acts as the central registry for volumes\n                          type: string\n                        tenant:\n                          description: |-\n                            tenant owning the given Quobyte volume in the Backend\n                            Used with dynamically provisioned Quobyte volumes, value is set by the plugin\n                          type: string\n                        user:\n                          description: |-\n                            user to map volume access to\n                            Defaults to serivceaccount user\n                          type: string\n                        volume:\n                          description: volume is a string that references an already created Quobyte volume by name.\n                          type: string\n                      required:\n                      - registry\n                      - volume\n                      type: object\n                    rbd:\n                      description: |-\n                        rbd represents a Rados Block Device mount on the host that shares a pod's lifetime.\n                        Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported.\n                        More info: https://examples.k8s.io/volumes/rbd/README.md\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd\n                          type: string\n                        image:\n                          description: |-\n                            image is the rados image name.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                        keyring:\n                          default: /etc/ceph/keyring\n                          description: |-\n                            keyring is the path to key ring for RBDUser.\n                            Default is /etc/ceph/keyring.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                        monitors:\n                          description: |-\n                            monitors is a collection of Ceph monitors.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        pool:\n                          default: rbd\n                          description: |-\n                            pool is the rados pool name.\n                            Default is rbd.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the ReadOnly setting in VolumeMounts.\n                            Defaults to false.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef is name of the authentication secret for RBDUser. If provided\n                            overrides keyring.\n                            Default is nil.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        user:\n                          default: admin\n                          description: |-\n                            user is the rados user name.\n                            Default is admin.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                      required:\n                      - image\n                      - monitors\n                      type: object\n                    scaleIO:\n                      description: |-\n                        scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.\n                        Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported.\n                      properties:\n                        fsType:\n                          default: xfs\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\".\n                            Default is \"xfs\".\n                          type: string\n                        gateway:\n                          description: gateway is the host address of the ScaleIO API Gateway.\n                          type: string\n                        protectionDomain:\n                          description: protectionDomain is the name of the ScaleIO Protection Domain for the configured storage.\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef references to the secret for ScaleIO user and other\n                            sensitive information. If this is not provided, Login operation will fail.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        sslEnabled:\n                          description: sslEnabled Flag enable/disable SSL communication with Gateway, default false\n                          type: boolean\n                        storageMode:\n                          default: ThinProvisioned\n                          description: |-\n                            storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.\n                            Default is ThinProvisioned.\n                          type: string\n                        storagePool:\n                          description: storagePool is the ScaleIO Storage Pool associated with the protection domain.\n                          type: string\n                        system:\n                          description: system is the name of the storage system as configured in ScaleIO.\n                          type: string\n                        volumeName:\n                          description: |-\n                            volumeName is the name of a volume already created in the ScaleIO system\n                            that is associated with this volume source.\n                          type: string\n                      required:\n                      - gateway\n                      - secretRef\n                      - system\n                      type: object\n                    secret:\n                      description: |-\n                        secret represents a secret that should populate this volume.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#secret\n                      properties:\n                        defaultMode:\n                          description: |-\n                            defaultMode is Optional: mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values\n                            for mode bits. Defaults to 0644.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        items:\n                          description: |-\n                            items If unspecified, each key-value pair in the Data field of the referenced\n                            Secret will be projected into the volume as a file whose name is the\n                            key and content is the value. If specified, the listed keys will be\n                            projected into the specified paths, and unlisted keys will not be\n                            present. If a key is specified which is not present in the Secret,\n                            the volume setup will error unless it is marked optional. Paths must be\n                            relative and may not contain the '..' path or start with '..'.\n                          items:\n                            description: Maps a string key to a path within a volume.\n                            properties:\n                              key:\n                                description: key is the key to project.\n                                type: string\n                              mode:\n                                description: |-\n                                  mode is Optional: mode bits used to set permissions on this file.\n                                  Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                  YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                  If not specified, the volume defaultMode will be used.\n                                  This might be in conflict with other options that affect the file\n                                  mode, like fsGroup, and the result can be other mode bits set.\n                                format: int32\n                                type: integer\n                              path:\n                                description: |-\n                                  path is the relative path of the file to map the key to.\n                                  May not be an absolute path.\n                                  May not contain the path element '..'.\n                                  May not start with the string '..'.\n                                type: string\n                            required:\n                            - key\n                            - path\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        optional:\n                          description: optional field specify whether the Secret or its keys must be defined\n                          type: boolean\n                        secretName:\n                          description: |-\n                            secretName is the name of the secret in the pod's namespace to use.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#secret\n                          type: string\n                      type: object\n                    storageos:\n                      description: |-\n                        storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes.\n                        Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef specifies the secret to use for obtaining the StorageOS API\n                            credentials.  If not specified, default values will be attempted.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        volumeName:\n                          description: |-\n                            volumeName is the human-readable name of the StorageOS volume.  Volume\n                            names are only unique within a namespace.\n                          type: string\n                        volumeNamespace:\n                          description: |-\n                            volumeNamespace specifies the scope of the volume within StorageOS.  If no\n                            namespace is specified then the Pod's namespace will be used.  This allows the\n                            Kubernetes name scoping to be mirrored within StorageOS for tighter integration.\n                            Set VolumeName to any name to override the default behaviour.\n                            Set to \"default\" if you are not using namespaces within StorageOS.\n                            Namespaces that do not pre-exist within StorageOS will be created.\n                          type: string\n                      type: object\n                    vsphereVolume:\n                      description: |-\n                        vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine.\n                        Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type\n                        are redirected to the csi.vsphere.vmware.com CSI driver.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        storagePolicyID:\n                          description: storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName.\n                          type: string\n                        storagePolicyName:\n                          description: storagePolicyName is the storage Policy Based Management (SPBM) profile name.\n                          type: string\n                        volumePath:\n                          description: volumePath is the path that identifies vSphere volume vmdk\n                          type: string\n                      required:\n                      - volumePath\n                      type: object\n                  required:\n                  - name\n                  type: object\n                type: array\n              web:\n                description: Defines the web command line flags when starting Alertmanager.\n                properties:\n                  getConcurrency:\n                    description: |-\n                      Maximum number of GET requests processed concurrently. This corresponds to the\n                      Alertmanager's `--web.get-concurrency` flag.\n                    format: int32\n                    type: integer\n                  httpConfig:\n                    description: Defines HTTP parameters for web server.\n                    properties:\n                      headers:\n                        description: List of headers that can be added to HTTP responses.\n                        properties:\n                          contentSecurityPolicy:\n                            description: |-\n                              Set the Content-Security-Policy header to HTTP responses.\n                              Unset if blank.\n                            type: string\n                          strictTransportSecurity:\n                            description: |-\n                              Set the Strict-Transport-Security header to HTTP responses.\n                              Unset if blank.\n                              Please make sure that you use this with care as this header might force\n                              browsers to load Prometheus and the other applications hosted on the same\n                              domain and subdomains over HTTPS.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security\n                            type: string\n                          xContentTypeOptions:\n                            description: |-\n                              Set the X-Content-Type-Options header to HTTP responses.\n                              Unset if blank. Accepted value is nosniff.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n                            enum:\n                            - \"\"\n                            - NoSniff\n                            type: string\n                          xFrameOptions:\n                            description: |-\n                              Set the X-Frame-Options header to HTTP responses.\n                              Unset if blank. Accepted values are deny and sameorigin.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n                            enum:\n                            - \"\"\n                            - Deny\n                            - SameOrigin\n                            type: string\n                          xXSSProtection:\n                            description: |-\n                              Set the X-XSS-Protection header to all responses.\n                              Unset if blank.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n                            type: string\n                        type: object\n                      http2:\n                        description: |-\n                          Enable HTTP/2 support. Note that HTTP/2 is only supported with TLS.\n                          When TLSConfig is not configured, HTTP/2 will be disabled.\n                          Whenever the value of the field changes, a rolling update will be triggered.\n                        type: boolean\n                    type: object\n                  timeout:\n                    description: |-\n                      Timeout for HTTP requests. This corresponds to the Alertmanager's\n                      `--web.timeout` flag.\n                    format: int32\n                    type: integer\n                  tlsConfig:\n                    description: Defines the TLS parameters for HTTPS.\n                    properties:\n                      cert:\n                        description: |-\n                          Secret or ConfigMap containing the TLS certificate for the web server.\n\n                          Either `keySecret` or `keyFile` must be defined.\n\n                          It is mutually exclusive with `certFile`.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      certFile:\n                        description: |-\n                          Path to the TLS certificate file in the container for the web server.\n\n                          Either `keySecret` or `keyFile` must be defined.\n\n                          It is mutually exclusive with `cert`.\n                        type: string\n                      cipherSuites:\n                        description: |-\n                          List of supported cipher suites for TLS versions up to TLS 1.2.\n\n                          If not defined, the Go default cipher suites are used.\n                          Available cipher suites are documented in the Go documentation:\n                          https://golang.org/pkg/crypto/tls/#pkg-constants\n                        items:\n                          type: string\n                        type: array\n                      client_ca:\n                        description: |-\n                          Secret or ConfigMap containing the CA certificate for client certificate\n                          authentication to the server.\n\n                          It is mutually exclusive with `clientCAFile`.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      clientAuthType:\n                        description: |-\n                          The server policy for client TLS authentication.\n\n                          For more detail on clientAuth options:\n                          https://golang.org/pkg/crypto/tls/#ClientAuthType\n                        type: string\n                      clientCAFile:\n                        description: |-\n                          Path to the CA certificate file for client certificate authentication to\n                          the server.\n\n                          It is mutually exclusive with `client_ca`.\n                        type: string\n                      curvePreferences:\n                        description: |-\n                          Elliptic curves that will be used in an ECDHE handshake, in preference\n                          order.\n\n                          Available curves are documented in the Go documentation:\n                          https://golang.org/pkg/crypto/tls/#CurveID\n                        items:\n                          type: string\n                        type: array\n                      keyFile:\n                        description: |-\n                          Path to the TLS private key file in the container for the web server.\n\n                          If defined, either `cert` or `certFile` must be defined.\n\n                          It is mutually exclusive with `keySecret`.\n                        type: string\n                      keySecret:\n                        description: |-\n                          Secret containing the TLS private key for the web server.\n\n                          Either `cert` or `certFile` must be defined.\n\n                          It is mutually exclusive with `keyFile`.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: Maximum TLS version that is acceptable.\n                        type: string\n                      minVersion:\n                        description: Minimum TLS version that is acceptable.\n                        type: string\n                      preferServerCipherSuites:\n                        description: |-\n                          Controls whether the server selects the client's most preferred cipher\n                          suite, or the server's most preferred cipher suite.\n\n                          If true then the server's preference, as expressed in\n                          the order of elements in cipherSuites, is used.\n                        type: boolean\n                    type: object\n                type: object\n            type: object\n          status:\n            description: |-\n              Most recent observed status of the Alertmanager cluster. Read-only.\n              More info:\n              https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n            properties:\n              availableReplicas:\n                description: |-\n                  Total number of available pods (ready for at least minReadySeconds)\n                  targeted by this Alertmanager cluster.\n                format: int32\n                type: integer\n              conditions:\n                description: The current state of the Alertmanager object.\n                items:\n                  description: |-\n                    Condition represents the state of the resources associated with the\n                    Prometheus, Alertmanager or ThanosRuler resource.\n                  properties:\n                    lastTransitionTime:\n                      description: lastTransitionTime is the time of the last update to the current status property.\n                      format: date-time\n                      type: string\n                    message:\n                      description: Human-readable message indicating details for the condition's last transition.\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        ObservedGeneration represents the .metadata.generation that the\n                        condition was set based upon. For instance, if `.metadata.generation` is\n                        currently 12, but the `.status.conditions[].observedGeneration` is 9, the\n                        condition is out of date with respect to the current state of the\n                        instance.\n                      format: int64\n                      type: integer\n                    reason:\n                      description: Reason for the condition's last transition.\n                      type: string\n                    status:\n                      description: Status of the condition.\n                      minLength: 1\n                      type: string\n                    type:\n                      description: Type of the condition being reported.\n                      minLength: 1\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - status\n                  - type\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              paused:\n                description: |-\n                  Represents whether any actions on the underlying managed objects are\n                  being performed. Only delete actions will be performed.\n                type: boolean\n              replicas:\n                description: |-\n                  Total number of non-terminated pods targeted by this Alertmanager\n                  object (their labels match the selector).\n                format: int32\n                type: integer\n              selector:\n                description: The selector used to match the pods targeted by this Alertmanager object.\n                type: string\n              unavailableReplicas:\n                description: Total number of unavailable pods targeted by this Alertmanager object.\n                format: int32\n                type: integer\n              updatedReplicas:\n                description: |-\n                  Total number of non-terminated pods targeted by this Alertmanager\n                  object that have the desired version spec.\n                format: int32\n                type: integer\n            required:\n            - availableReplicas\n            - paused\n            - replicas\n            - unavailableReplicas\n            - updatedReplicas\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      scale:\n        labelSelectorPath: .status.selector\n        specReplicasPath: .spec.replicas\n        statusReplicasPath: .status.replicas\n      status: {}\n"
  },
  {
    "path": "hack/config/monitoring/crds/0podmonitorCustomResourceDefinition.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.18.0\n    operator.prometheus.io/version: 0.85.0\n  name: podmonitors.monitoring.coreos.com\nspec:\n  group: monitoring.coreos.com\n  names:\n    categories:\n    - prometheus-operator\n    kind: PodMonitor\n    listKind: PodMonitorList\n    plural: podmonitors\n    shortNames:\n    - pmon\n    singular: podmonitor\n  scope: Namespaced\n  versions:\n  - name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The `PodMonitor` custom resource definition (CRD) defines how `Prometheus` and `PrometheusAgent` can scrape metrics from a group of pods.\n          Among other things, it allows to specify:\n          * The pods to scrape via label selectors.\n          * The container ports to scrape.\n          * Authentication credentials to use.\n          * Target and metric relabeling.\n\n          `Prometheus` and `PrometheusAgent` objects select `PodMonitor` objects using label and namespace selectors.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Specification of desired Pod selection for target discovery by Prometheus.\n            properties:\n              attachMetadata:\n                description: |-\n                  `attachMetadata` defines additional metadata which is added to the\n                  discovered targets.\n\n                  It requires Prometheus >= v2.35.0.\n                properties:\n                  node:\n                    description: |-\n                      When set to true, Prometheus attaches node metadata to the discovered\n                      targets.\n\n                      The Prometheus service account must have the `list` and `watch`\n                      permissions on the `Nodes` objects.\n                    type: boolean\n                type: object\n              bodySizeLimit:\n                description: |-\n                  When defined, bodySizeLimit specifies a job level limit on the size\n                  of uncompressed response body that will be accepted by Prometheus.\n\n                  It requires Prometheus >= v2.28.0.\n                pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$\n                type: string\n              convertClassicHistogramsToNHCB:\n                description: |-\n                  Whether to convert all scraped classic histograms into a native histogram with custom buckets.\n                  It requires Prometheus >= v3.0.0.\n                type: boolean\n              fallbackScrapeProtocol:\n                description: |-\n                  The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type.\n\n                  It requires Prometheus >= v3.0.0.\n                enum:\n                - PrometheusProto\n                - OpenMetricsText0.0.1\n                - OpenMetricsText1.0.0\n                - PrometheusText0.0.4\n                - PrometheusText1.0.0\n                type: string\n              jobLabel:\n                description: |-\n                  The label to use to retrieve the job name from.\n                  `jobLabel` selects the label from the associated Kubernetes `Pod`\n                  object which will be used as the `job` label for all metrics.\n\n                  For example if `jobLabel` is set to `foo` and the Kubernetes `Pod`\n                  object is labeled with `foo: bar`, then Prometheus adds the `job=\"bar\"`\n                  label to all ingested metrics.\n\n                  If the value of this field is empty, the `job` label of the metrics\n                  defaults to the namespace and name of the PodMonitor object (e.g. `<namespace>/<name>`).\n                type: string\n              keepDroppedTargets:\n                description: |-\n                  Per-scrape limit on the number of targets dropped by relabeling\n                  that will be kept in memory. 0 means no limit.\n\n                  It requires Prometheus >= v2.47.0.\n                format: int64\n                type: integer\n              labelLimit:\n                description: |-\n                  Per-scrape limit on number of labels that will be accepted for a sample.\n\n                  It requires Prometheus >= v2.27.0.\n                format: int64\n                type: integer\n              labelNameLengthLimit:\n                description: |-\n                  Per-scrape limit on length of labels name that will be accepted for a sample.\n\n                  It requires Prometheus >= v2.27.0.\n                format: int64\n                type: integer\n              labelValueLengthLimit:\n                description: |-\n                  Per-scrape limit on length of labels value that will be accepted for a sample.\n\n                  It requires Prometheus >= v2.27.0.\n                format: int64\n                type: integer\n              namespaceSelector:\n                description: |-\n                  `namespaceSelector` defines in which namespace(s) Prometheus should discover the pods.\n                  By default, the pods are discovered in the same namespace as the `PodMonitor` object but it is possible to select pods across different/all namespaces.\n                properties:\n                  any:\n                    description: |-\n                      Boolean describing whether all namespaces are selected in contrast to a\n                      list restricting them.\n                    type: boolean\n                  matchNames:\n                    description: List of namespace names to select from.\n                    items:\n                      type: string\n                    type: array\n                type: object\n              nativeHistogramBucketLimit:\n                description: |-\n                  If there are more than this many buckets in a native histogram,\n                  buckets will be merged to stay within the limit.\n                  It requires Prometheus >= v2.45.0.\n                format: int64\n                type: integer\n              nativeHistogramMinBucketFactor:\n                anyOf:\n                - type: integer\n                - type: string\n                description: |-\n                  If the growth factor of one bucket to the next is smaller than this,\n                  buckets will be merged to increase the factor sufficiently.\n                  It requires Prometheus >= v2.50.0.\n                pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                x-kubernetes-int-or-string: true\n              podMetricsEndpoints:\n                description: Defines how to scrape metrics from the selected pods.\n                items:\n                  description: |-\n                    PodMetricsEndpoint defines an endpoint serving Prometheus metrics to be scraped by\n                    Prometheus.\n                  properties:\n                    authorization:\n                      description: |-\n                        `authorization` configures the Authorization header credentials to use when\n                        scraping the target.\n\n                        Cannot be set at the same time as `basicAuth`, or `oauth2`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: |-\n                        `basicAuth` configures the Basic Authentication credentials to use when\n                        scraping the target.\n\n                        Cannot be set at the same time as `authorization`, or `oauth2`.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    bearerTokenSecret:\n                      description: |-\n                        `bearerTokenSecret` specifies a key of a Secret containing the bearer\n                        token for scraping targets. The secret needs to be in the same namespace\n                        as the PodMonitor object and readable by the Prometheus Operator.\n\n                        Deprecated: use `authorization` instead.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    enableHttp2:\n                      description: '`enableHttp2` can be used to disable HTTP2 when scraping the target.'\n                      type: boolean\n                    filterRunning:\n                      description: |-\n                        When true, the pods which are not running (e.g. either in Failed or\n                        Succeeded state) are dropped during the target discovery.\n\n                        If unset, the filtering is enabled.\n\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase\n                      type: boolean\n                    followRedirects:\n                      description: |-\n                        `followRedirects` defines whether the scrape requests should follow HTTP\n                        3xx redirects.\n                      type: boolean\n                    honorLabels:\n                      description: |-\n                        When true, `honorLabels` preserves the metric's labels when they collide\n                        with the target's labels.\n                      type: boolean\n                    honorTimestamps:\n                      description: |-\n                        `honorTimestamps` controls whether Prometheus preserves the timestamps\n                        when exposed by the target.\n                      type: boolean\n                    interval:\n                      description: |-\n                        Interval at which Prometheus scrapes the metrics from the target.\n\n                        If empty, Prometheus uses the global scrape interval.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    metricRelabelings:\n                      description: |-\n                        `metricRelabelings` configures the relabeling rules to apply to the\n                        samples before ingestion.\n                      items:\n                        description: |-\n                          RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                          scraped samples and remote write samples.\n\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        properties:\n                          action:\n                            default: replace\n                            description: |-\n                              Action to perform based on the regex matching.\n\n                              `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                              `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                              Default: \"Replace\"\n                            enum:\n                            - replace\n                            - Replace\n                            - keep\n                            - Keep\n                            - drop\n                            - Drop\n                            - hashmod\n                            - HashMod\n                            - labelmap\n                            - LabelMap\n                            - labeldrop\n                            - LabelDrop\n                            - labelkeep\n                            - LabelKeep\n                            - lowercase\n                            - Lowercase\n                            - uppercase\n                            - Uppercase\n                            - keepequal\n                            - KeepEqual\n                            - dropequal\n                            - DropEqual\n                            type: string\n                          modulus:\n                            description: |-\n                              Modulus to take of the hash of the source label values.\n\n                              Only applicable when the action is `HashMod`.\n                            format: int64\n                            type: integer\n                          regex:\n                            description: Regular expression against which the extracted value is matched.\n                            type: string\n                          replacement:\n                            description: |-\n                              Replacement value against which a Replace action is performed if the\n                              regular expression matches.\n\n                              Regex capture groups are available.\n                            type: string\n                          separator:\n                            description: Separator is the string between concatenated SourceLabels.\n                            type: string\n                          sourceLabels:\n                            description: |-\n                              The source labels select values from existing labels. Their content is\n                              concatenated using the configured Separator and matched against the\n                              configured regular expression.\n                            items:\n                              description: |-\n                                LabelName is a valid Prometheus label name which may only contain ASCII\n                                letters, numbers, as well as underscores.\n                              pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                              type: string\n                            type: array\n                          targetLabel:\n                            description: |-\n                              Label to which the resulting string is written in a replacement.\n\n                              It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                              `KeepEqual` and `DropEqual` actions.\n\n                              Regex capture groups are available.\n                            type: string\n                        type: object\n                      type: array\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        `oauth2` configures the OAuth2 settings to use when scraping the target.\n\n                        It requires Prometheus >= 2.27.0.\n\n                        Cannot be set at the same time as `authorization`, or `basicAuth`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    params:\n                      additionalProperties:\n                        items:\n                          type: string\n                        type: array\n                      description: '`params` define optional HTTP URL parameters.'\n                      type: object\n                    path:\n                      description: |-\n                        HTTP path from which to scrape for metrics.\n\n                        If empty, Prometheus uses the default value (e.g. `/metrics`).\n                      type: string\n                    port:\n                      description: |-\n                        The `Pod` port name which exposes the endpoint.\n\n                        It takes precedence over the `portNumber` and `targetPort` fields.\n                      type: string\n                    portNumber:\n                      description: The `Pod` port number which exposes the endpoint.\n                      format: int32\n                      maximum: 65535\n                      minimum: 1\n                      type: integer\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    relabelings:\n                      description: |-\n                        `relabelings` configures the relabeling rules to apply the target's\n                        metadata labels.\n\n                        The Operator automatically adds relabelings for a few standard Kubernetes fields.\n\n                        The original scrape job's name is available via the `__tmp_prometheus_job_name` label.\n\n                        More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                      items:\n                        description: |-\n                          RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                          scraped samples and remote write samples.\n\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        properties:\n                          action:\n                            default: replace\n                            description: |-\n                              Action to perform based on the regex matching.\n\n                              `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                              `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                              Default: \"Replace\"\n                            enum:\n                            - replace\n                            - Replace\n                            - keep\n                            - Keep\n                            - drop\n                            - Drop\n                            - hashmod\n                            - HashMod\n                            - labelmap\n                            - LabelMap\n                            - labeldrop\n                            - LabelDrop\n                            - labelkeep\n                            - LabelKeep\n                            - lowercase\n                            - Lowercase\n                            - uppercase\n                            - Uppercase\n                            - keepequal\n                            - KeepEqual\n                            - dropequal\n                            - DropEqual\n                            type: string\n                          modulus:\n                            description: |-\n                              Modulus to take of the hash of the source label values.\n\n                              Only applicable when the action is `HashMod`.\n                            format: int64\n                            type: integer\n                          regex:\n                            description: Regular expression against which the extracted value is matched.\n                            type: string\n                          replacement:\n                            description: |-\n                              Replacement value against which a Replace action is performed if the\n                              regular expression matches.\n\n                              Regex capture groups are available.\n                            type: string\n                          separator:\n                            description: Separator is the string between concatenated SourceLabels.\n                            type: string\n                          sourceLabels:\n                            description: |-\n                              The source labels select values from existing labels. Their content is\n                              concatenated using the configured Separator and matched against the\n                              configured regular expression.\n                            items:\n                              description: |-\n                                LabelName is a valid Prometheus label name which may only contain ASCII\n                                letters, numbers, as well as underscores.\n                              pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                              type: string\n                            type: array\n                          targetLabel:\n                            description: |-\n                              Label to which the resulting string is written in a replacement.\n\n                              It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                              `KeepEqual` and `DropEqual` actions.\n\n                              Regex capture groups are available.\n                            type: string\n                        type: object\n                      type: array\n                    scheme:\n                      description: |-\n                        HTTP scheme to use for scraping.\n\n                        `http` and `https` are the expected values unless you rewrite the\n                        `__scheme__` label via relabeling.\n\n                        If empty, Prometheus uses the default value `http`.\n                      enum:\n                      - http\n                      - https\n                      type: string\n                    scrapeTimeout:\n                      description: |-\n                        Timeout after which Prometheus considers the scrape to be failed.\n\n                        If empty, Prometheus uses the global scrape timeout unless it is less\n                        than the target's scrape interval value in which the latter is used.\n                        The value cannot be greater than the scrape interval otherwise the operator will reject the resource.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    targetPort:\n                      anyOf:\n                      - type: integer\n                      - type: string\n                      description: |-\n                        Name or number of the target port of the `Pod` object behind the Service, the\n                        port must be specified with container port property.\n\n                        Deprecated: use 'port' or 'portNumber' instead.\n                      x-kubernetes-int-or-string: true\n                    tlsConfig:\n                      description: TLS configuration to use when scraping the target.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                    trackTimestampsStaleness:\n                      description: |-\n                        `trackTimestampsStaleness` defines whether Prometheus tracks staleness of\n                        the metrics that have an explicit timestamp present in scraped data.\n                        Has no effect if `honorTimestamps` is false.\n\n                        It requires Prometheus >= v2.48.0.\n                      type: boolean\n                  type: object\n                type: array\n              podTargetLabels:\n                description: |-\n                  `podTargetLabels` defines the labels which are transferred from the\n                  associated Kubernetes `Pod` object onto the ingested metrics.\n                items:\n                  type: string\n                type: array\n              sampleLimit:\n                description: |-\n                  `sampleLimit` defines a per-scrape limit on the number of scraped samples\n                  that will be accepted.\n                format: int64\n                type: integer\n              scrapeClass:\n                description: The scrape class to apply.\n                minLength: 1\n                type: string\n              scrapeClassicHistograms:\n                description: |-\n                  Whether to scrape a classic histogram that is also exposed as a native histogram.\n                  It requires Prometheus >= v2.45.0.\n\n                  Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration.\n                type: boolean\n              scrapeProtocols:\n                description: |-\n                  `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the\n                  protocols supported by Prometheus in order of preference (from most to least preferred).\n\n                  If unset, Prometheus uses its default value.\n\n                  It requires Prometheus >= v2.49.0.\n                items:\n                  description: |-\n                    ScrapeProtocol represents a protocol used by Prometheus for scraping metrics.\n                    Supported values are:\n                    * `OpenMetricsText0.0.1`\n                    * `OpenMetricsText1.0.0`\n                    * `PrometheusProto`\n                    * `PrometheusText0.0.4`\n                    * `PrometheusText1.0.0`\n                  enum:\n                  - PrometheusProto\n                  - OpenMetricsText0.0.1\n                  - OpenMetricsText1.0.0\n                  - PrometheusText0.0.4\n                  - PrometheusText1.0.0\n                  type: string\n                type: array\n                x-kubernetes-list-type: set\n              selector:\n                description: Label selector to select the Kubernetes `Pod` objects to scrape metrics from.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              selectorMechanism:\n                description: |-\n                  Mechanism used to select the endpoints to scrape.\n                  By default, the selection process relies on relabel configurations to filter the discovered targets.\n                  Alternatively, you can opt in for role selectors, which may offer better efficiency in large clusters.\n                  Which strategy is best for your use case needs to be carefully evaluated.\n\n                  It requires Prometheus >= v2.17.0.\n                enum:\n                - RelabelConfig\n                - RoleSelector\n                type: string\n              targetLimit:\n                description: |-\n                  `targetLimit` defines a limit on the number of scraped targets that will\n                  be accepted.\n                format: int64\n                type: integer\n            required:\n            - selector\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n"
  },
  {
    "path": "hack/config/monitoring/crds/0probeCustomResourceDefinition.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.18.0\n    operator.prometheus.io/version: 0.85.0\n  name: probes.monitoring.coreos.com\nspec:\n  group: monitoring.coreos.com\n  names:\n    categories:\n    - prometheus-operator\n    kind: Probe\n    listKind: ProbeList\n    plural: probes\n    shortNames:\n    - prb\n    singular: probe\n  scope: Namespaced\n  versions:\n  - name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The `Probe` custom resource definition (CRD) defines how to scrape metrics from prober exporters such as the [blackbox exporter](https://github.com/prometheus/blackbox_exporter).\n\n          The `Probe` resource needs 2 pieces of information:\n          * The list of probed addresses which can be defined statically or by discovering Kubernetes Ingress objects.\n          * The prober which exposes the availability of probed endpoints (over various protocols such HTTP, TCP, ICMP, ...) as Prometheus metrics.\n\n          `Prometheus` and `PrometheusAgent` objects select `Probe` objects using label and namespace selectors.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Specification of desired Ingress selection for target discovery by Prometheus.\n            properties:\n              authorization:\n                description: Authorization section for this endpoint\n                properties:\n                  credentials:\n                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  type:\n                    description: |-\n                      Defines the authentication type. The value is case-insensitive.\n\n                      \"Basic\" is not a supported value.\n\n                      Default: \"Bearer\"\n                    type: string\n                type: object\n              basicAuth:\n                description: |-\n                  BasicAuth allow an endpoint to authenticate over basic authentication.\n                  More info: https://prometheus.io/docs/operating/configuration/#endpoint\n                properties:\n                  password:\n                    description: |-\n                      `password` specifies a key of a Secret containing the password for\n                      authentication.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  username:\n                    description: |-\n                      `username` specifies a key of a Secret containing the username for\n                      authentication.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                type: object\n              bearerTokenSecret:\n                description: |-\n                  Secret to mount to read bearer token for scraping targets. The secret\n                  needs to be in the same namespace as the probe and accessible by\n                  the Prometheus Operator.\n                properties:\n                  key:\n                    description: The key of the secret to select from.  Must be a valid secret key.\n                    type: string\n                  name:\n                    default: \"\"\n                    description: |-\n                      Name of the referent.\n                      This field is effectively required, but due to backwards compatibility is\n                      allowed to be empty. Instances of this type with an empty value here are\n                      almost certainly wrong.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                    type: string\n                  optional:\n                    description: Specify whether the Secret or its key must be defined\n                    type: boolean\n                required:\n                - key\n                type: object\n                x-kubernetes-map-type: atomic\n              convertClassicHistogramsToNHCB:\n                description: |-\n                  Whether to convert all scraped classic histograms into a native histogram with custom buckets.\n                  It requires Prometheus >= v3.0.0.\n                type: boolean\n              fallbackScrapeProtocol:\n                description: |-\n                  The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type.\n\n                  It requires Prometheus >= v3.0.0.\n                enum:\n                - PrometheusProto\n                - OpenMetricsText0.0.1\n                - OpenMetricsText1.0.0\n                - PrometheusText0.0.4\n                - PrometheusText1.0.0\n                type: string\n              interval:\n                description: |-\n                  Interval at which targets are probed using the configured prober.\n                  If not specified Prometheus' global scrape interval is used.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              jobName:\n                description: The job name assigned to scraped metrics by default.\n                type: string\n              keepDroppedTargets:\n                description: |-\n                  Per-scrape limit on the number of targets dropped by relabeling\n                  that will be kept in memory. 0 means no limit.\n\n                  It requires Prometheus >= v2.47.0.\n                format: int64\n                type: integer\n              labelLimit:\n                description: |-\n                  Per-scrape limit on number of labels that will be accepted for a sample.\n                  Only valid in Prometheus versions 2.27.0 and newer.\n                format: int64\n                type: integer\n              labelNameLengthLimit:\n                description: |-\n                  Per-scrape limit on length of labels name that will be accepted for a sample.\n                  Only valid in Prometheus versions 2.27.0 and newer.\n                format: int64\n                type: integer\n              labelValueLengthLimit:\n                description: |-\n                  Per-scrape limit on length of labels value that will be accepted for a sample.\n                  Only valid in Prometheus versions 2.27.0 and newer.\n                format: int64\n                type: integer\n              metricRelabelings:\n                description: MetricRelabelConfigs to apply to samples before ingestion.\n                items:\n                  description: |-\n                    RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                    scraped samples and remote write samples.\n\n                    More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                  properties:\n                    action:\n                      default: replace\n                      description: |-\n                        Action to perform based on the regex matching.\n\n                        `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                        `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                        Default: \"Replace\"\n                      enum:\n                      - replace\n                      - Replace\n                      - keep\n                      - Keep\n                      - drop\n                      - Drop\n                      - hashmod\n                      - HashMod\n                      - labelmap\n                      - LabelMap\n                      - labeldrop\n                      - LabelDrop\n                      - labelkeep\n                      - LabelKeep\n                      - lowercase\n                      - Lowercase\n                      - uppercase\n                      - Uppercase\n                      - keepequal\n                      - KeepEqual\n                      - dropequal\n                      - DropEqual\n                      type: string\n                    modulus:\n                      description: |-\n                        Modulus to take of the hash of the source label values.\n\n                        Only applicable when the action is `HashMod`.\n                      format: int64\n                      type: integer\n                    regex:\n                      description: Regular expression against which the extracted value is matched.\n                      type: string\n                    replacement:\n                      description: |-\n                        Replacement value against which a Replace action is performed if the\n                        regular expression matches.\n\n                        Regex capture groups are available.\n                      type: string\n                    separator:\n                      description: Separator is the string between concatenated SourceLabels.\n                      type: string\n                    sourceLabels:\n                      description: |-\n                        The source labels select values from existing labels. Their content is\n                        concatenated using the configured Separator and matched against the\n                        configured regular expression.\n                      items:\n                        description: |-\n                          LabelName is a valid Prometheus label name which may only contain ASCII\n                          letters, numbers, as well as underscores.\n                        pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                        type: string\n                      type: array\n                    targetLabel:\n                      description: |-\n                        Label to which the resulting string is written in a replacement.\n\n                        It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                        `KeepEqual` and `DropEqual` actions.\n\n                        Regex capture groups are available.\n                      type: string\n                  type: object\n                type: array\n              module:\n                description: |-\n                  The module to use for probing specifying how to probe the target.\n                  Example module configuring in the blackbox exporter:\n                  https://github.com/prometheus/blackbox_exporter/blob/master/example.yml\n                type: string\n              nativeHistogramBucketLimit:\n                description: |-\n                  If there are more than this many buckets in a native histogram,\n                  buckets will be merged to stay within the limit.\n                  It requires Prometheus >= v2.45.0.\n                format: int64\n                type: integer\n              nativeHistogramMinBucketFactor:\n                anyOf:\n                - type: integer\n                - type: string\n                description: |-\n                  If the growth factor of one bucket to the next is smaller than this,\n                  buckets will be merged to increase the factor sufficiently.\n                  It requires Prometheus >= v2.50.0.\n                pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                x-kubernetes-int-or-string: true\n              oauth2:\n                description: OAuth2 for the URL. Only valid in Prometheus versions 2.27.0 and newer.\n                properties:\n                  clientId:\n                    description: |-\n                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                      OAuth2 client's ID.\n                    properties:\n                      configMap:\n                        description: ConfigMap containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key to select.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the ConfigMap or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      secret:\n                        description: Secret containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  clientSecret:\n                    description: |-\n                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                      client's secret.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  endpointParams:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      `endpointParams` configures the HTTP parameters to append to the token\n                      URL.\n                    type: object\n                  noProxy:\n                    description: |-\n                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                      that should be excluded from proxying. IP and domain names can\n                      contain port numbers.\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: string\n                  proxyConnectHeader:\n                    additionalProperties:\n                      items:\n                        description: SecretKeySelector selects a key of a Secret.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      type: array\n                    description: |-\n                      ProxyConnectHeader optionally specifies headers to send to\n                      proxies during CONNECT requests.\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  proxyFromEnvironment:\n                    description: |-\n                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: boolean\n                  proxyUrl:\n                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                    pattern: ^(http|https|socks5)://.+$\n                    type: string\n                  scopes:\n                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                    items:\n                      type: string\n                    type: array\n                  tlsConfig:\n                    description: |-\n                      TLS configuration to use when connecting to the OAuth2 server.\n                      It requires Prometheus >= v2.43.0.\n                    properties:\n                      ca:\n                        description: Certificate authority used when verifying server certificates.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      cert:\n                        description: Client certificate to present when doing client-authentication.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      insecureSkipVerify:\n                        description: Disable target certificate validation.\n                        type: boolean\n                      keySecret:\n                        description: Secret containing the client key file for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: |-\n                          Maximum acceptable TLS version.\n\n                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      minVersion:\n                        description: |-\n                          Minimum acceptable TLS version.\n\n                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      serverName:\n                        description: Used to verify the hostname for the targets.\n                        type: string\n                    type: object\n                  tokenUrl:\n                    description: '`tokenURL` configures the URL to fetch the token from.'\n                    minLength: 1\n                    type: string\n                required:\n                - clientId\n                - clientSecret\n                - tokenUrl\n                type: object\n              params:\n                description: |-\n                  The list of HTTP query parameters for the scrape.\n                  Please note that the `.spec.module` field takes precedence over the `module` parameter from this list when both are defined.\n                  The module name must be added using Module under ProbeSpec.\n                items:\n                  description: ProbeParam defines specification of extra parameters for a Probe.\n                  properties:\n                    name:\n                      description: The parameter name\n                      minLength: 1\n                      type: string\n                    values:\n                      description: The parameter values\n                      items:\n                        minLength: 1\n                        type: string\n                      minItems: 1\n                      type: array\n                  required:\n                  - name\n                  type: object\n                minItems: 1\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n              prober:\n                description: |-\n                  Specification for the prober to use for probing targets.\n                  The prober.URL parameter is required. Targets cannot be probed if left empty.\n                properties:\n                  noProxy:\n                    description: |-\n                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                      that should be excluded from proxying. IP and domain names can\n                      contain port numbers.\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: string\n                  path:\n                    default: /probe\n                    description: |-\n                      Path to collect metrics from.\n                      Defaults to `/probe`.\n                    type: string\n                  proxyConnectHeader:\n                    additionalProperties:\n                      items:\n                        description: SecretKeySelector selects a key of a Secret.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      type: array\n                    description: |-\n                      ProxyConnectHeader optionally specifies headers to send to\n                      proxies during CONNECT requests.\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  proxyFromEnvironment:\n                    description: |-\n                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: boolean\n                  proxyUrl:\n                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                    pattern: ^(http|https|socks5)://.+$\n                    type: string\n                  scheme:\n                    description: |-\n                      HTTP scheme to use for scraping.\n                      `http` and `https` are the expected values unless you rewrite the `__scheme__` label via relabeling.\n                      If empty, Prometheus uses the default value `http`.\n                    enum:\n                    - http\n                    - https\n                    type: string\n                  url:\n                    description: Mandatory URL of the prober.\n                    type: string\n                required:\n                - url\n                type: object\n              sampleLimit:\n                description: SampleLimit defines per-scrape limit on number of scraped samples that will be accepted.\n                format: int64\n                type: integer\n              scrapeClass:\n                description: The scrape class to apply.\n                minLength: 1\n                type: string\n              scrapeClassicHistograms:\n                description: |-\n                  Whether to scrape a classic histogram that is also exposed as a native histogram.\n                  It requires Prometheus >= v2.45.0.\n\n                  Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration.\n                type: boolean\n              scrapeProtocols:\n                description: |-\n                  `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the\n                  protocols supported by Prometheus in order of preference (from most to least preferred).\n\n                  If unset, Prometheus uses its default value.\n\n                  It requires Prometheus >= v2.49.0.\n                items:\n                  description: |-\n                    ScrapeProtocol represents a protocol used by Prometheus for scraping metrics.\n                    Supported values are:\n                    * `OpenMetricsText0.0.1`\n                    * `OpenMetricsText1.0.0`\n                    * `PrometheusProto`\n                    * `PrometheusText0.0.4`\n                    * `PrometheusText1.0.0`\n                  enum:\n                  - PrometheusProto\n                  - OpenMetricsText0.0.1\n                  - OpenMetricsText1.0.0\n                  - PrometheusText0.0.4\n                  - PrometheusText1.0.0\n                  type: string\n                type: array\n                x-kubernetes-list-type: set\n              scrapeTimeout:\n                description: |-\n                  Timeout for scraping metrics from the Prometheus exporter.\n                  If not specified, the Prometheus global scrape timeout is used.\n                  The value cannot be greater than the scrape interval otherwise the operator will reject the resource.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              targetLimit:\n                description: TargetLimit defines a limit on the number of scraped targets that will be accepted.\n                format: int64\n                type: integer\n              targets:\n                description: Targets defines a set of static or dynamically discovered targets to probe.\n                properties:\n                  ingress:\n                    description: |-\n                      ingress defines the Ingress objects to probe and the relabeling\n                      configuration.\n                      If `staticConfig` is also defined, `staticConfig` takes precedence.\n                    properties:\n                      namespaceSelector:\n                        description: From which namespaces to select Ingress objects.\n                        properties:\n                          any:\n                            description: |-\n                              Boolean describing whether all namespaces are selected in contrast to a\n                              list restricting them.\n                            type: boolean\n                          matchNames:\n                            description: List of namespace names to select from.\n                            items:\n                              type: string\n                            type: array\n                        type: object\n                      relabelingConfigs:\n                        description: |-\n                          RelabelConfigs to apply to the label set of the target before it gets\n                          scraped.\n                          The original ingress address is available via the\n                          `__tmp_prometheus_ingress_address` label. It can be used to customize the\n                          probed URL.\n                          The original scrape job's name is available via the `__tmp_prometheus_job_name` label.\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        items:\n                          description: |-\n                            RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                            scraped samples and remote write samples.\n\n                            More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                          properties:\n                            action:\n                              default: replace\n                              description: |-\n                                Action to perform based on the regex matching.\n\n                                `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                                `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                                Default: \"Replace\"\n                              enum:\n                              - replace\n                              - Replace\n                              - keep\n                              - Keep\n                              - drop\n                              - Drop\n                              - hashmod\n                              - HashMod\n                              - labelmap\n                              - LabelMap\n                              - labeldrop\n                              - LabelDrop\n                              - labelkeep\n                              - LabelKeep\n                              - lowercase\n                              - Lowercase\n                              - uppercase\n                              - Uppercase\n                              - keepequal\n                              - KeepEqual\n                              - dropequal\n                              - DropEqual\n                              type: string\n                            modulus:\n                              description: |-\n                                Modulus to take of the hash of the source label values.\n\n                                Only applicable when the action is `HashMod`.\n                              format: int64\n                              type: integer\n                            regex:\n                              description: Regular expression against which the extracted value is matched.\n                              type: string\n                            replacement:\n                              description: |-\n                                Replacement value against which a Replace action is performed if the\n                                regular expression matches.\n\n                                Regex capture groups are available.\n                              type: string\n                            separator:\n                              description: Separator is the string between concatenated SourceLabels.\n                              type: string\n                            sourceLabels:\n                              description: |-\n                                The source labels select values from existing labels. Their content is\n                                concatenated using the configured Separator and matched against the\n                                configured regular expression.\n                              items:\n                                description: |-\n                                  LabelName is a valid Prometheus label name which may only contain ASCII\n                                  letters, numbers, as well as underscores.\n                                pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                                type: string\n                              type: array\n                            targetLabel:\n                              description: |-\n                                Label to which the resulting string is written in a replacement.\n\n                                It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                                `KeepEqual` and `DropEqual` actions.\n\n                                Regex capture groups are available.\n                              type: string\n                          type: object\n                        type: array\n                      selector:\n                        description: Selector to select the Ingress objects.\n                        properties:\n                          matchExpressions:\n                            description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                            items:\n                              description: |-\n                                A label selector requirement is a selector that contains values, a key, and an operator that\n                                relates the key and values.\n                              properties:\n                                key:\n                                  description: key is the label key that the selector applies to.\n                                  type: string\n                                operator:\n                                  description: |-\n                                    operator represents a key's relationship to a set of values.\n                                    Valid operators are In, NotIn, Exists and DoesNotExist.\n                                  type: string\n                                values:\n                                  description: |-\n                                    values is an array of string values. If the operator is In or NotIn,\n                                    the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                    the values array must be empty. This array is replaced during a strategic\n                                    merge patch.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              required:\n                              - key\n                              - operator\n                              type: object\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          matchLabels:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                              map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                              operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                            type: object\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  staticConfig:\n                    description: |-\n                      staticConfig defines the static list of targets to probe and the\n                      relabeling configuration.\n                      If `ingress` is also defined, `staticConfig` takes precedence.\n                      More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#static_config.\n                    properties:\n                      labels:\n                        additionalProperties:\n                          type: string\n                        description: Labels assigned to all metrics scraped from the targets.\n                        type: object\n                      relabelingConfigs:\n                        description: |-\n                          RelabelConfigs to apply to the label set of the targets before it gets\n                          scraped.\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        items:\n                          description: |-\n                            RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                            scraped samples and remote write samples.\n\n                            More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                          properties:\n                            action:\n                              default: replace\n                              description: |-\n                                Action to perform based on the regex matching.\n\n                                `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                                `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                                Default: \"Replace\"\n                              enum:\n                              - replace\n                              - Replace\n                              - keep\n                              - Keep\n                              - drop\n                              - Drop\n                              - hashmod\n                              - HashMod\n                              - labelmap\n                              - LabelMap\n                              - labeldrop\n                              - LabelDrop\n                              - labelkeep\n                              - LabelKeep\n                              - lowercase\n                              - Lowercase\n                              - uppercase\n                              - Uppercase\n                              - keepequal\n                              - KeepEqual\n                              - dropequal\n                              - DropEqual\n                              type: string\n                            modulus:\n                              description: |-\n                                Modulus to take of the hash of the source label values.\n\n                                Only applicable when the action is `HashMod`.\n                              format: int64\n                              type: integer\n                            regex:\n                              description: Regular expression against which the extracted value is matched.\n                              type: string\n                            replacement:\n                              description: |-\n                                Replacement value against which a Replace action is performed if the\n                                regular expression matches.\n\n                                Regex capture groups are available.\n                              type: string\n                            separator:\n                              description: Separator is the string between concatenated SourceLabels.\n                              type: string\n                            sourceLabels:\n                              description: |-\n                                The source labels select values from existing labels. Their content is\n                                concatenated using the configured Separator and matched against the\n                                configured regular expression.\n                              items:\n                                description: |-\n                                  LabelName is a valid Prometheus label name which may only contain ASCII\n                                  letters, numbers, as well as underscores.\n                                pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                                type: string\n                              type: array\n                            targetLabel:\n                              description: |-\n                                Label to which the resulting string is written in a replacement.\n\n                                It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                                `KeepEqual` and `DropEqual` actions.\n\n                                Regex capture groups are available.\n                              type: string\n                          type: object\n                        type: array\n                      static:\n                        description: The list of hosts to probe.\n                        items:\n                          type: string\n                        type: array\n                    type: object\n                type: object\n              tlsConfig:\n                description: TLS configuration to use when scraping the endpoint.\n                properties:\n                  ca:\n                    description: Certificate authority used when verifying server certificates.\n                    properties:\n                      configMap:\n                        description: ConfigMap containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key to select.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the ConfigMap or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      secret:\n                        description: Secret containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  cert:\n                    description: Client certificate to present when doing client-authentication.\n                    properties:\n                      configMap:\n                        description: ConfigMap containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key to select.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the ConfigMap or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      secret:\n                        description: Secret containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  insecureSkipVerify:\n                    description: Disable target certificate validation.\n                    type: boolean\n                  keySecret:\n                    description: Secret containing the client key file for the targets.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  maxVersion:\n                    description: |-\n                      Maximum acceptable TLS version.\n\n                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                    enum:\n                    - TLS10\n                    - TLS11\n                    - TLS12\n                    - TLS13\n                    type: string\n                  minVersion:\n                    description: |-\n                      Minimum acceptable TLS version.\n\n                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                    enum:\n                    - TLS10\n                    - TLS11\n                    - TLS12\n                    - TLS13\n                    type: string\n                  serverName:\n                    description: Used to verify the hostname for the targets.\n                    type: string\n                type: object\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n"
  },
  {
    "path": "hack/config/monitoring/crds/0prometheusCustomResourceDefinition.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.18.0\n    operator.prometheus.io/version: 0.85.0\n  name: prometheuses.monitoring.coreos.com\nspec:\n  group: monitoring.coreos.com\n  names:\n    categories:\n    - prometheus-operator\n    kind: Prometheus\n    listKind: PrometheusList\n    plural: prometheuses\n    shortNames:\n    - prom\n    singular: prometheus\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - description: The version of Prometheus\n      jsonPath: .spec.version\n      name: Version\n      type: string\n    - description: The number of desired replicas\n      jsonPath: .spec.replicas\n      name: Desired\n      type: integer\n    - description: The number of ready replicas\n      jsonPath: .status.availableReplicas\n      name: Ready\n      type: integer\n    - jsonPath: .status.conditions[?(@.type == 'Reconciled')].status\n      name: Reconciled\n      type: string\n    - jsonPath: .status.conditions[?(@.type == 'Available')].status\n      name: Available\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    - description: Whether the resource reconciliation is paused or not\n      jsonPath: .status.paused\n      name: Paused\n      priority: 1\n      type: boolean\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The `Prometheus` custom resource definition (CRD) defines a desired [Prometheus](https://prometheus.io/docs/prometheus) setup to run in a Kubernetes cluster. It allows to specify many options such as the number of replicas, persistent storage, and Alertmanagers where firing alerts should be sent and many more.\n\n          For each `Prometheus` resource, the Operator deploys one or several `StatefulSet` objects in the same namespace. The number of StatefulSets is equal to the number of shards which is 1 by default.\n\n          The resource defines via label and namespace selectors which `ServiceMonitor`, `PodMonitor`, `Probe` and `PrometheusRule` objects should be associated to the deployed Prometheus instances.\n\n          The Operator continuously reconciles the scrape and rules configuration and a sidecar container running in the Prometheus pods triggers a reload of the configuration when needed.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: |-\n              Specification of the desired behavior of the Prometheus cluster. More info:\n              https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n            properties:\n              additionalAlertManagerConfigs:\n                description: |-\n                  AdditionalAlertManagerConfigs specifies a key of a Secret containing\n                  additional Prometheus Alertmanager configurations. The Alertmanager\n                  configurations are appended to the configuration generated by the\n                  Prometheus Operator. They must be formatted according to the official\n                  Prometheus documentation:\n\n                  https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alertmanager_config\n\n                  The user is responsible for making sure that the configurations are valid\n\n                  Note that using this feature may expose the possibility to break\n                  upgrades of Prometheus. It is advised to review Prometheus release notes\n                  to ensure that no incompatible AlertManager configs are going to break\n                  Prometheus after the upgrade.\n                properties:\n                  key:\n                    description: The key of the secret to select from.  Must be a valid secret key.\n                    type: string\n                  name:\n                    default: \"\"\n                    description: |-\n                      Name of the referent.\n                      This field is effectively required, but due to backwards compatibility is\n                      allowed to be empty. Instances of this type with an empty value here are\n                      almost certainly wrong.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                    type: string\n                  optional:\n                    description: Specify whether the Secret or its key must be defined\n                    type: boolean\n                required:\n                - key\n                type: object\n                x-kubernetes-map-type: atomic\n              additionalAlertRelabelConfigs:\n                description: |-\n                  AdditionalAlertRelabelConfigs specifies a key of a Secret containing\n                  additional Prometheus alert relabel configurations. The alert relabel\n                  configurations are appended to the configuration generated by the\n                  Prometheus Operator. They must be formatted according to the official\n                  Prometheus documentation:\n\n                  https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alert_relabel_configs\n\n                  The user is responsible for making sure that the configurations are valid\n\n                  Note that using this feature may expose the possibility to break\n                  upgrades of Prometheus. It is advised to review Prometheus release notes\n                  to ensure that no incompatible alert relabel configs are going to break\n                  Prometheus after the upgrade.\n                properties:\n                  key:\n                    description: The key of the secret to select from.  Must be a valid secret key.\n                    type: string\n                  name:\n                    default: \"\"\n                    description: |-\n                      Name of the referent.\n                      This field is effectively required, but due to backwards compatibility is\n                      allowed to be empty. Instances of this type with an empty value here are\n                      almost certainly wrong.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                    type: string\n                  optional:\n                    description: Specify whether the Secret or its key must be defined\n                    type: boolean\n                required:\n                - key\n                type: object\n                x-kubernetes-map-type: atomic\n              additionalArgs:\n                description: |-\n                  AdditionalArgs allows setting additional arguments for the 'prometheus' container.\n\n                  It is intended for e.g. activating hidden flags which are not supported by\n                  the dedicated configuration options yet. The arguments are passed as-is to the\n                  Prometheus container which may cause issues if they are invalid or not supported\n                  by the given Prometheus version.\n\n                  In case of an argument conflict (e.g. an argument which is already set by the\n                  operator itself) or when providing an invalid argument, the reconciliation will\n                  fail and an error will be logged.\n                items:\n                  description: Argument as part of the AdditionalArgs list.\n                  properties:\n                    name:\n                      description: Name of the argument, e.g. \"scrape.discovery-reload-interval\".\n                      minLength: 1\n                      type: string\n                    value:\n                      description: Argument value, e.g. 30s. Can be empty for name-only arguments (e.g. --storage.tsdb.no-lockfile)\n                      type: string\n                  required:\n                  - name\n                  type: object\n                type: array\n              additionalScrapeConfigs:\n                description: |-\n                  AdditionalScrapeConfigs allows specifying a key of a Secret containing\n                  additional Prometheus scrape configurations. Scrape configurations\n                  specified are appended to the configurations generated by the Prometheus\n                  Operator. Job configurations specified must have the form as specified\n                  in the official Prometheus documentation:\n                  https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config.\n                  As scrape configs are appended, the user is responsible to make sure it\n                  is valid. Note that using this feature may expose the possibility to\n                  break upgrades of Prometheus. It is advised to review Prometheus release\n                  notes to ensure that no incompatible scrape configs are going to break\n                  Prometheus after the upgrade.\n                properties:\n                  key:\n                    description: The key of the secret to select from.  Must be a valid secret key.\n                    type: string\n                  name:\n                    default: \"\"\n                    description: |-\n                      Name of the referent.\n                      This field is effectively required, but due to backwards compatibility is\n                      allowed to be empty. Instances of this type with an empty value here are\n                      almost certainly wrong.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                    type: string\n                  optional:\n                    description: Specify whether the Secret or its key must be defined\n                    type: boolean\n                required:\n                - key\n                type: object\n                x-kubernetes-map-type: atomic\n              affinity:\n                description: Defines the Pods' affinity scheduling rules if specified.\n                properties:\n                  nodeAffinity:\n                    description: Describes node affinity scheduling rules for the pod.\n                    properties:\n                      preferredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          The scheduler will prefer to schedule pods to nodes that satisfy\n                          the affinity expressions specified by this field, but it may choose\n                          a node that violates one or more of the expressions. The node that is\n                          most preferred is the one with the greatest sum of weights, i.e.\n                          for each node that meets all of the scheduling requirements (resource\n                          request, requiredDuringScheduling affinity expressions, etc.),\n                          compute a sum by iterating through the elements of this field and adding\n                          \"weight\" to the sum if the node matches the corresponding matchExpressions; the\n                          node(s) with the highest sum are the most preferred.\n                        items:\n                          description: |-\n                            An empty preferred scheduling term matches all objects with implicit weight 0\n                            (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).\n                          properties:\n                            preference:\n                              description: A node selector term, associated with the corresponding weight.\n                              properties:\n                                matchExpressions:\n                                  description: A list of node selector requirements by node's labels.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchFields:\n                                  description: A list of node selector requirements by node's fields.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            weight:\n                              description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.\n                              format: int32\n                              type: integer\n                          required:\n                          - preference\n                          - weight\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                      requiredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          If the affinity requirements specified by this field are not met at\n                          scheduling time, the pod will not be scheduled onto the node.\n                          If the affinity requirements specified by this field cease to be met\n                          at some point during pod execution (e.g. due to an update), the system\n                          may or may not try to eventually evict the pod from its node.\n                        properties:\n                          nodeSelectorTerms:\n                            description: Required. A list of node selector terms. The terms are ORed.\n                            items:\n                              description: |-\n                                A null or empty node selector term matches no objects. The requirements of\n                                them are ANDed.\n                                The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.\n                              properties:\n                                matchExpressions:\n                                  description: A list of node selector requirements by node's labels.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchFields:\n                                  description: A list of node selector requirements by node's fields.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                            x-kubernetes-list-type: atomic\n                        required:\n                        - nodeSelectorTerms\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  podAffinity:\n                    description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)).\n                    properties:\n                      preferredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          The scheduler will prefer to schedule pods to nodes that satisfy\n                          the affinity expressions specified by this field, but it may choose\n                          a node that violates one or more of the expressions. The node that is\n                          most preferred is the one with the greatest sum of weights, i.e.\n                          for each node that meets all of the scheduling requirements (resource\n                          request, requiredDuringScheduling affinity expressions, etc.),\n                          compute a sum by iterating through the elements of this field and adding\n                          \"weight\" to the sum if the node has pods which matches the corresponding podAffinityTerm; the\n                          node(s) with the highest sum are the most preferred.\n                        items:\n                          description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)\n                          properties:\n                            podAffinityTerm:\n                              description: Required. A pod affinity term, associated with the corresponding weight.\n                              properties:\n                                labelSelector:\n                                  description: |-\n                                    A label query over a set of resources, in this case pods.\n                                    If it's null, this PodAffinityTerm matches with no Pods.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                matchLabelKeys:\n                                  description: |-\n                                    MatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                    Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                mismatchLabelKeys:\n                                  description: |-\n                                    MismatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                    Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                namespaceSelector:\n                                  description: |-\n                                    A label query over the set of namespaces that the term applies to.\n                                    The term is applied to the union of the namespaces selected by this field\n                                    and the ones listed in the namespaces field.\n                                    null selector and null or empty namespaces list means \"this pod's namespace\".\n                                    An empty selector ({}) matches all namespaces.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                namespaces:\n                                  description: |-\n                                    namespaces specifies a static list of namespace names that the term applies to.\n                                    The term is applied to the union of the namespaces listed in this field\n                                    and the ones selected by namespaceSelector.\n                                    null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                topologyKey:\n                                  description: |-\n                                    This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                    the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                    whose value of the label with key topologyKey matches that of any node on which any of the\n                                    selected pods is running.\n                                    Empty topologyKey is not allowed.\n                                  type: string\n                              required:\n                              - topologyKey\n                              type: object\n                            weight:\n                              description: |-\n                                weight associated with matching the corresponding podAffinityTerm,\n                                in the range 1-100.\n                              format: int32\n                              type: integer\n                          required:\n                          - podAffinityTerm\n                          - weight\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                      requiredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          If the affinity requirements specified by this field are not met at\n                          scheduling time, the pod will not be scheduled onto the node.\n                          If the affinity requirements specified by this field cease to be met\n                          at some point during pod execution (e.g. due to a pod label update), the\n                          system may or may not try to eventually evict the pod from its node.\n                          When there are multiple elements, the lists of nodes corresponding to each\n                          podAffinityTerm are intersected, i.e. all terms must be satisfied.\n                        items:\n                          description: |-\n                            Defines a set of pods (namely those matching the labelSelector\n                            relative to the given namespace(s)) that this pod should be\n                            co-located (affinity) or not co-located (anti-affinity) with,\n                            where co-located is defined as running on a node whose value of\n                            the label with key <topologyKey> matches that of any node on which\n                            a pod of the set of pods is running\n                          properties:\n                            labelSelector:\n                              description: |-\n                                A label query over a set of resources, in this case pods.\n                                If it's null, this PodAffinityTerm matches with no Pods.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            matchLabelKeys:\n                              description: |-\n                                MatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            mismatchLabelKeys:\n                              description: |-\n                                MismatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            namespaceSelector:\n                              description: |-\n                                A label query over the set of namespaces that the term applies to.\n                                The term is applied to the union of the namespaces selected by this field\n                                and the ones listed in the namespaces field.\n                                null selector and null or empty namespaces list means \"this pod's namespace\".\n                                An empty selector ({}) matches all namespaces.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            namespaces:\n                              description: |-\n                                namespaces specifies a static list of namespace names that the term applies to.\n                                The term is applied to the union of the namespaces listed in this field\n                                and the ones selected by namespaceSelector.\n                                null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            topologyKey:\n                              description: |-\n                                This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                whose value of the label with key topologyKey matches that of any node on which any of the\n                                selected pods is running.\n                                Empty topologyKey is not allowed.\n                              type: string\n                          required:\n                          - topologyKey\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                    type: object\n                  podAntiAffinity:\n                    description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).\n                    properties:\n                      preferredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          The scheduler will prefer to schedule pods to nodes that satisfy\n                          the anti-affinity expressions specified by this field, but it may choose\n                          a node that violates one or more of the expressions. The node that is\n                          most preferred is the one with the greatest sum of weights, i.e.\n                          for each node that meets all of the scheduling requirements (resource\n                          request, requiredDuringScheduling anti-affinity expressions, etc.),\n                          compute a sum by iterating through the elements of this field and adding\n                          \"weight\" to the sum if the node has pods which matches the corresponding podAffinityTerm; the\n                          node(s) with the highest sum are the most preferred.\n                        items:\n                          description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)\n                          properties:\n                            podAffinityTerm:\n                              description: Required. A pod affinity term, associated with the corresponding weight.\n                              properties:\n                                labelSelector:\n                                  description: |-\n                                    A label query over a set of resources, in this case pods.\n                                    If it's null, this PodAffinityTerm matches with no Pods.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                matchLabelKeys:\n                                  description: |-\n                                    MatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                    Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                mismatchLabelKeys:\n                                  description: |-\n                                    MismatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                    Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                namespaceSelector:\n                                  description: |-\n                                    A label query over the set of namespaces that the term applies to.\n                                    The term is applied to the union of the namespaces selected by this field\n                                    and the ones listed in the namespaces field.\n                                    null selector and null or empty namespaces list means \"this pod's namespace\".\n                                    An empty selector ({}) matches all namespaces.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                namespaces:\n                                  description: |-\n                                    namespaces specifies a static list of namespace names that the term applies to.\n                                    The term is applied to the union of the namespaces listed in this field\n                                    and the ones selected by namespaceSelector.\n                                    null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                topologyKey:\n                                  description: |-\n                                    This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                    the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                    whose value of the label with key topologyKey matches that of any node on which any of the\n                                    selected pods is running.\n                                    Empty topologyKey is not allowed.\n                                  type: string\n                              required:\n                              - topologyKey\n                              type: object\n                            weight:\n                              description: |-\n                                weight associated with matching the corresponding podAffinityTerm,\n                                in the range 1-100.\n                              format: int32\n                              type: integer\n                          required:\n                          - podAffinityTerm\n                          - weight\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                      requiredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          If the anti-affinity requirements specified by this field are not met at\n                          scheduling time, the pod will not be scheduled onto the node.\n                          If the anti-affinity requirements specified by this field cease to be met\n                          at some point during pod execution (e.g. due to a pod label update), the\n                          system may or may not try to eventually evict the pod from its node.\n                          When there are multiple elements, the lists of nodes corresponding to each\n                          podAffinityTerm are intersected, i.e. all terms must be satisfied.\n                        items:\n                          description: |-\n                            Defines a set of pods (namely those matching the labelSelector\n                            relative to the given namespace(s)) that this pod should be\n                            co-located (affinity) or not co-located (anti-affinity) with,\n                            where co-located is defined as running on a node whose value of\n                            the label with key <topologyKey> matches that of any node on which\n                            a pod of the set of pods is running\n                          properties:\n                            labelSelector:\n                              description: |-\n                                A label query over a set of resources, in this case pods.\n                                If it's null, this PodAffinityTerm matches with no Pods.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            matchLabelKeys:\n                              description: |-\n                                MatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            mismatchLabelKeys:\n                              description: |-\n                                MismatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            namespaceSelector:\n                              description: |-\n                                A label query over the set of namespaces that the term applies to.\n                                The term is applied to the union of the namespaces selected by this field\n                                and the ones listed in the namespaces field.\n                                null selector and null or empty namespaces list means \"this pod's namespace\".\n                                An empty selector ({}) matches all namespaces.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            namespaces:\n                              description: |-\n                                namespaces specifies a static list of namespace names that the term applies to.\n                                The term is applied to the union of the namespaces listed in this field\n                                and the ones selected by namespaceSelector.\n                                null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            topologyKey:\n                              description: |-\n                                This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                whose value of the label with key topologyKey matches that of any node on which any of the\n                                selected pods is running.\n                                Empty topologyKey is not allowed.\n                              type: string\n                          required:\n                          - topologyKey\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                    type: object\n                type: object\n              alerting:\n                description: Defines the settings related to Alertmanager.\n                properties:\n                  alertmanagers:\n                    description: Alertmanager endpoints where Prometheus should send alerts to.\n                    items:\n                      description: |-\n                        AlertmanagerEndpoints defines a selection of a single Endpoints object\n                        containing Alertmanager IPs to fire alerts against.\n                      properties:\n                        alertRelabelings:\n                          description: |-\n                            Relabeling configs applied before sending alerts to a specific Alertmanager.\n                            It requires Prometheus >= v2.51.0.\n                          items:\n                            description: |-\n                              RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                              scraped samples and remote write samples.\n\n                              More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                            properties:\n                              action:\n                                default: replace\n                                description: |-\n                                  Action to perform based on the regex matching.\n\n                                  `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                                  `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                                  Default: \"Replace\"\n                                enum:\n                                - replace\n                                - Replace\n                                - keep\n                                - Keep\n                                - drop\n                                - Drop\n                                - hashmod\n                                - HashMod\n                                - labelmap\n                                - LabelMap\n                                - labeldrop\n                                - LabelDrop\n                                - labelkeep\n                                - LabelKeep\n                                - lowercase\n                                - Lowercase\n                                - uppercase\n                                - Uppercase\n                                - keepequal\n                                - KeepEqual\n                                - dropequal\n                                - DropEqual\n                                type: string\n                              modulus:\n                                description: |-\n                                  Modulus to take of the hash of the source label values.\n\n                                  Only applicable when the action is `HashMod`.\n                                format: int64\n                                type: integer\n                              regex:\n                                description: Regular expression against which the extracted value is matched.\n                                type: string\n                              replacement:\n                                description: |-\n                                  Replacement value against which a Replace action is performed if the\n                                  regular expression matches.\n\n                                  Regex capture groups are available.\n                                type: string\n                              separator:\n                                description: Separator is the string between concatenated SourceLabels.\n                                type: string\n                              sourceLabels:\n                                description: |-\n                                  The source labels select values from existing labels. Their content is\n                                  concatenated using the configured Separator and matched against the\n                                  configured regular expression.\n                                items:\n                                  description: |-\n                                    LabelName is a valid Prometheus label name which may only contain ASCII\n                                    letters, numbers, as well as underscores.\n                                  pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                                  type: string\n                                type: array\n                              targetLabel:\n                                description: |-\n                                  Label to which the resulting string is written in a replacement.\n\n                                  It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                                  `KeepEqual` and `DropEqual` actions.\n\n                                  Regex capture groups are available.\n                                type: string\n                            type: object\n                          type: array\n                        apiVersion:\n                          description: |-\n                            Version of the Alertmanager API that Prometheus uses to send alerts.\n                            It can be \"V1\" or \"V2\".\n                            The field has no effect for Prometheus >= v3.0.0 because only the v2 API is supported.\n                          enum:\n                          - v1\n                          - V1\n                          - v2\n                          - V2\n                          type: string\n                        authorization:\n                          description: |-\n                            Authorization section for Alertmanager.\n\n                            Cannot be set at the same time as `basicAuth`, `bearerTokenFile` or `sigv4`.\n                          properties:\n                            credentials:\n                              description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type:\n                              description: |-\n                                Defines the authentication type. The value is case-insensitive.\n\n                                \"Basic\" is not a supported value.\n\n                                Default: \"Bearer\"\n                              type: string\n                          type: object\n                        basicAuth:\n                          description: |-\n                            BasicAuth configuration for Alertmanager.\n\n                            Cannot be set at the same time as `bearerTokenFile`, `authorization` or `sigv4`.\n                          properties:\n                            password:\n                              description: |-\n                                `password` specifies a key of a Secret containing the password for\n                                authentication.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            username:\n                              description: |-\n                                `username` specifies a key of a Secret containing the username for\n                                authentication.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        bearerTokenFile:\n                          description: |-\n                            File to read bearer token for Alertmanager.\n\n                            Cannot be set at the same time as `basicAuth`, `authorization`, or `sigv4`.\n\n                            Deprecated: this will be removed in a future release. Prefer using `authorization`.\n                          type: string\n                        enableHttp2:\n                          description: Whether to enable HTTP2.\n                          type: boolean\n                        name:\n                          description: Name of the Endpoints object in the namespace.\n                          minLength: 1\n                          type: string\n                        namespace:\n                          description: |-\n                            Namespace of the Endpoints object.\n\n                            If not set, the object will be discovered in the namespace of the\n                            Prometheus object.\n                          minLength: 1\n                          type: string\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        pathPrefix:\n                          description: Prefix for the HTTP path alerts are pushed to.\n                          type: string\n                        port:\n                          anyOf:\n                          - type: integer\n                          - type: string\n                          description: Port on which the Alertmanager API is exposed.\n                          x-kubernetes-int-or-string: true\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        relabelings:\n                          description: Relabel configuration applied to the discovered Alertmanagers.\n                          items:\n                            description: |-\n                              RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                              scraped samples and remote write samples.\n\n                              More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                            properties:\n                              action:\n                                default: replace\n                                description: |-\n                                  Action to perform based on the regex matching.\n\n                                  `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                                  `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                                  Default: \"Replace\"\n                                enum:\n                                - replace\n                                - Replace\n                                - keep\n                                - Keep\n                                - drop\n                                - Drop\n                                - hashmod\n                                - HashMod\n                                - labelmap\n                                - LabelMap\n                                - labeldrop\n                                - LabelDrop\n                                - labelkeep\n                                - LabelKeep\n                                - lowercase\n                                - Lowercase\n                                - uppercase\n                                - Uppercase\n                                - keepequal\n                                - KeepEqual\n                                - dropequal\n                                - DropEqual\n                                type: string\n                              modulus:\n                                description: |-\n                                  Modulus to take of the hash of the source label values.\n\n                                  Only applicable when the action is `HashMod`.\n                                format: int64\n                                type: integer\n                              regex:\n                                description: Regular expression against which the extracted value is matched.\n                                type: string\n                              replacement:\n                                description: |-\n                                  Replacement value against which a Replace action is performed if the\n                                  regular expression matches.\n\n                                  Regex capture groups are available.\n                                type: string\n                              separator:\n                                description: Separator is the string between concatenated SourceLabels.\n                                type: string\n                              sourceLabels:\n                                description: |-\n                                  The source labels select values from existing labels. Their content is\n                                  concatenated using the configured Separator and matched against the\n                                  configured regular expression.\n                                items:\n                                  description: |-\n                                    LabelName is a valid Prometheus label name which may only contain ASCII\n                                    letters, numbers, as well as underscores.\n                                  pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                                  type: string\n                                type: array\n                              targetLabel:\n                                description: |-\n                                  Label to which the resulting string is written in a replacement.\n\n                                  It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                                  `KeepEqual` and `DropEqual` actions.\n\n                                  Regex capture groups are available.\n                                type: string\n                            type: object\n                          type: array\n                        scheme:\n                          description: Scheme to use when firing alerts.\n                          type: string\n                        sigv4:\n                          description: |-\n                            Sigv4 allows to configures AWS's Signature Verification 4 for the URL.\n\n                            It requires Prometheus >= v2.48.0.\n\n                            Cannot be set at the same time as `basicAuth`, `bearerTokenFile` or `authorization`.\n                          properties:\n                            accessKey:\n                              description: |-\n                                AccessKey is the AWS API key. If not specified, the environment variable\n                                `AWS_ACCESS_KEY_ID` is used.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            profile:\n                              description: Profile is the named AWS profile used to authenticate.\n                              type: string\n                            region:\n                              description: Region is the AWS region. If blank, the region from the default credentials chain used.\n                              type: string\n                            roleArn:\n                              description: RoleArn is the named AWS profile used to authenticate.\n                              type: string\n                            secretKey:\n                              description: |-\n                                SecretKey is the AWS API secret. If not specified, the environment\n                                variable `AWS_SECRET_ACCESS_KEY` is used.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        timeout:\n                          description: Timeout is a per-target Alertmanager timeout when pushing alerts.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                        tlsConfig:\n                          description: TLS Config to use for Alertmanager.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            caFile:\n                              description: Path to the CA cert in the Prometheus container to use for the targets.\n                              type: string\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            certFile:\n                              description: Path to the client cert file in the Prometheus container for the targets.\n                              type: string\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keyFile:\n                              description: Path to the client key file in the Prometheus container for the targets.\n                              type: string\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                      required:\n                      - name\n                      - port\n                      type: object\n                    type: array\n                required:\n                - alertmanagers\n                type: object\n              allowOverlappingBlocks:\n                description: |-\n                  AllowOverlappingBlocks enables vertical compaction and vertical query\n                  merge in Prometheus.\n\n                  Deprecated: this flag has no effect for Prometheus >= 2.39.0 where overlapping blocks are enabled by default.\n                type: boolean\n              apiserverConfig:\n                description: |-\n                  APIServerConfig allows specifying a host and auth methods to access the\n                  Kuberntees API server.\n                  If null, Prometheus is assumed to run inside of the cluster: it will\n                  discover the API servers automatically and use the Pod's CA certificate\n                  and bearer token file at /var/run/secrets/kubernetes.io/serviceaccount/.\n                properties:\n                  authorization:\n                    description: |-\n                      Authorization section for the API server.\n\n                      Cannot be set at the same time as `basicAuth`, `bearerToken`, or\n                      `bearerTokenFile`.\n                    properties:\n                      credentials:\n                        description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      credentialsFile:\n                        description: File to read a secret from, mutually exclusive with `credentials`.\n                        type: string\n                      type:\n                        description: |-\n                          Defines the authentication type. The value is case-insensitive.\n\n                          \"Basic\" is not a supported value.\n\n                          Default: \"Bearer\"\n                        type: string\n                    type: object\n                  basicAuth:\n                    description: |-\n                      BasicAuth configuration for the API server.\n\n                      Cannot be set at the same time as `authorization`, `bearerToken`, or\n                      `bearerTokenFile`.\n                    properties:\n                      password:\n                        description: |-\n                          `password` specifies a key of a Secret containing the password for\n                          authentication.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      username:\n                        description: |-\n                          `username` specifies a key of a Secret containing the username for\n                          authentication.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  bearerToken:\n                    description: |-\n                      *Warning: this field shouldn't be used because the token value appears\n                      in clear-text. Prefer using `authorization`.*\n\n                      Deprecated: this will be removed in a future release.\n                    type: string\n                  bearerTokenFile:\n                    description: |-\n                      File to read bearer token for accessing apiserver.\n\n                      Cannot be set at the same time as `basicAuth`, `authorization`, or `bearerToken`.\n\n                      Deprecated: this will be removed in a future release. Prefer using `authorization`.\n                    type: string\n                  host:\n                    description: |-\n                      Kubernetes API address consisting of a hostname or IP address followed\n                      by an optional port number.\n                    type: string\n                  noProxy:\n                    description: |-\n                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                      that should be excluded from proxying. IP and domain names can\n                      contain port numbers.\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: string\n                  proxyConnectHeader:\n                    additionalProperties:\n                      items:\n                        description: SecretKeySelector selects a key of a Secret.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      type: array\n                    description: |-\n                      ProxyConnectHeader optionally specifies headers to send to\n                      proxies during CONNECT requests.\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  proxyFromEnvironment:\n                    description: |-\n                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: boolean\n                  proxyUrl:\n                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                    pattern: ^(http|https|socks5)://.+$\n                    type: string\n                  tlsConfig:\n                    description: TLS Config to use for the API server.\n                    properties:\n                      ca:\n                        description: Certificate authority used when verifying server certificates.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      caFile:\n                        description: Path to the CA cert in the Prometheus container to use for the targets.\n                        type: string\n                      cert:\n                        description: Client certificate to present when doing client-authentication.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      certFile:\n                        description: Path to the client cert file in the Prometheus container for the targets.\n                        type: string\n                      insecureSkipVerify:\n                        description: Disable target certificate validation.\n                        type: boolean\n                      keyFile:\n                        description: Path to the client key file in the Prometheus container for the targets.\n                        type: string\n                      keySecret:\n                        description: Secret containing the client key file for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: |-\n                          Maximum acceptable TLS version.\n\n                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      minVersion:\n                        description: |-\n                          Minimum acceptable TLS version.\n\n                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      serverName:\n                        description: Used to verify the hostname for the targets.\n                        type: string\n                    type: object\n                required:\n                - host\n                type: object\n              arbitraryFSAccessThroughSMs:\n                description: |-\n                  When true, ServiceMonitor, PodMonitor and Probe object are forbidden to\n                  reference arbitrary files on the file system of the 'prometheus'\n                  container.\n                  When a ServiceMonitor's endpoint specifies a `bearerTokenFile` value\n                  (e.g.  '/var/run/secrets/kubernetes.io/serviceaccount/token'), a\n                  malicious target can get access to the Prometheus service account's\n                  token in the Prometheus' scrape request. Setting\n                  `spec.arbitraryFSAccessThroughSM` to 'true' would prevent the attack.\n                  Users should instead provide the credentials using the\n                  `spec.bearerTokenSecret` field.\n                properties:\n                  deny:\n                    type: boolean\n                type: object\n              automountServiceAccountToken:\n                description: |-\n                  AutomountServiceAccountToken indicates whether a service account token should be automatically mounted in the pod.\n                  If the field isn't set, the operator mounts the service account token by default.\n\n                  **Warning:** be aware that by default, Prometheus requires the service account token for Kubernetes service discovery.\n                  It is possible to use strategic merge patch to project the service account token into the 'prometheus' container.\n                type: boolean\n              baseImage:\n                description: 'Deprecated: use ''spec.image'' instead.'\n                type: string\n              bodySizeLimit:\n                description: |-\n                  BodySizeLimit defines per-scrape on response body size.\n                  Only valid in Prometheus versions 2.45.0 and newer.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedBodySizeLimit.\n                pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$\n                type: string\n              configMaps:\n                description: |-\n                  ConfigMaps is a list of ConfigMaps in the same namespace as the Prometheus\n                  object, which shall be mounted into the Prometheus Pods.\n                  Each ConfigMap is added to the StatefulSet definition as a volume named `configmap-<configmap-name>`.\n                  The ConfigMaps are mounted into /etc/prometheus/configmaps/<configmap-name> in the 'prometheus' container.\n                items:\n                  type: string\n                type: array\n              containers:\n                description: |-\n                  Containers allows injecting additional containers or modifying operator\n                  generated containers. This can be used to allow adding an authentication\n                  proxy to the Pods or to change the behavior of an operator generated\n                  container. Containers described here modify an operator generated\n                  container if they share the same name and modifications are done via a\n                  strategic merge patch.\n\n                  The names of containers managed by the operator are:\n                  * `prometheus`\n                  * `config-reloader`\n                  * `thanos-sidecar`\n\n                  Overriding containers is entirely outside the scope of what the\n                  maintainers will support and by doing so, you accept that this behaviour\n                  may break at any time without notice.\n                items:\n                  description: A single application container that you want to run within a pod.\n                  properties:\n                    args:\n                      description: |-\n                        Arguments to the entrypoint.\n                        The container image's CMD is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    command:\n                      description: |-\n                        Entrypoint array. Not executed within a shell.\n                        The container image's ENTRYPOINT is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    env:\n                      description: |-\n                        List of environment variables to set in the container.\n                        Cannot be updated.\n                      items:\n                        description: EnvVar represents an environment variable present in a Container.\n                        properties:\n                          name:\n                            description: Name of the environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          value:\n                            description: |-\n                              Variable references $(VAR_NAME) are expanded\n                              using the previously defined environment variables in the container and\n                              any service environment variables. If a variable cannot be resolved,\n                              the reference in the input string will be unchanged. Double $$ are reduced\n                              to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.\n                              \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\".\n                              Escaped references will never be expanded, regardless of whether the variable\n                              exists or not.\n                              Defaults to \"\".\n                            type: string\n                          valueFrom:\n                            description: Source for the environment variable's value. Cannot be used if value is not empty.\n                            properties:\n                              configMapKeyRef:\n                                description: Selects a key of a ConfigMap.\n                                properties:\n                                  key:\n                                    description: The key to select.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the ConfigMap or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              fieldRef:\n                                description: |-\n                                  Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,\n                                  spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.\n                                properties:\n                                  apiVersion:\n                                    description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                    type: string\n                                  fieldPath:\n                                    description: Path of the field to select in the specified API version.\n                                    type: string\n                                required:\n                                - fieldPath\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              resourceFieldRef:\n                                description: |-\n                                  Selects a resource of the container: only resources limits and requests\n                                  (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.\n                                properties:\n                                  containerName:\n                                    description: 'Container name: required for volumes, optional for env vars'\n                                    type: string\n                                  divisor:\n                                    anyOf:\n                                    - type: integer\n                                    - type: string\n                                    description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                    x-kubernetes-int-or-string: true\n                                  resource:\n                                    description: 'Required: resource to select'\n                                    type: string\n                                required:\n                                - resource\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              secretKeyRef:\n                                description: Selects a key of a secret in the pod's namespace\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            type: object\n                        required:\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - name\n                      x-kubernetes-list-type: map\n                    envFrom:\n                      description: |-\n                        List of sources to populate environment variables in the container.\n                        The keys defined within a source must be a C_IDENTIFIER. All invalid keys\n                        will be reported as an event when the container is starting. When a key exists in multiple\n                        sources, the value associated with the last source will take precedence.\n                        Values defined by an Env with a duplicate key will take precedence.\n                        Cannot be updated.\n                      items:\n                        description: EnvFromSource represents the source of a set of ConfigMaps or Secrets\n                        properties:\n                          configMapRef:\n                            description: The ConfigMap to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          prefix:\n                            description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          secretRef:\n                            description: The Secret to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    image:\n                      description: |-\n                        Container image name.\n                        More info: https://kubernetes.io/docs/concepts/containers/images\n                        This field is optional to allow higher level config management to default or override\n                        container images in workload controllers like Deployments and StatefulSets.\n                      type: string\n                    imagePullPolicy:\n                      description: |-\n                        Image pull policy.\n                        One of Always, Never, IfNotPresent.\n                        Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/containers/images#updating-images\n                      type: string\n                    lifecycle:\n                      description: |-\n                        Actions that the management system should take in response to container lifecycle events.\n                        Cannot be updated.\n                      properties:\n                        postStart:\n                          description: |-\n                            PostStart is called immediately after a container is created. If the handler fails,\n                            the container is terminated and restarted according to its restart policy.\n                            Other management of the container blocks until the hook completes.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        preStop:\n                          description: |-\n                            PreStop is called immediately before a container is terminated due to an\n                            API request or management event such as liveness/startup probe failure,\n                            preemption, resource contention, etc. The handler is not called if the\n                            container crashes or exits. The Pod's termination grace period countdown begins before the\n                            PreStop hook is executed. Regardless of the outcome of the handler, the\n                            container will eventually terminate within the Pod's termination grace\n                            period (unless delayed by finalizers). Other management of the container blocks until the hook completes\n                            or until the termination grace period is reached.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        stopSignal:\n                          description: |-\n                            StopSignal defines which signal will be sent to a container when it is being stopped.\n                            If not specified, the default is defined by the container runtime in use.\n                            StopSignal can only be set for Pods with a non-empty .spec.os.name\n                          type: string\n                      type: object\n                    livenessProbe:\n                      description: |-\n                        Periodic probe of container liveness.\n                        Container will be restarted if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    name:\n                      description: |-\n                        Name of the container specified as a DNS_LABEL.\n                        Each container in a pod must have a unique name (DNS_LABEL).\n                        Cannot be updated.\n                      type: string\n                    ports:\n                      description: |-\n                        List of ports to expose from the container. Not specifying a port here\n                        DOES NOT prevent that port from being exposed. Any port which is\n                        listening on the default \"0.0.0.0\" address inside a container will be\n                        accessible from the network.\n                        Modifying this array with strategic merge patch may corrupt the data.\n                        For more information See https://github.com/kubernetes/kubernetes/issues/108255.\n                        Cannot be updated.\n                      items:\n                        description: ContainerPort represents a network port in a single container.\n                        properties:\n                          containerPort:\n                            description: |-\n                              Number of port to expose on the pod's IP address.\n                              This must be a valid port number, 0 < x < 65536.\n                            format: int32\n                            type: integer\n                          hostIP:\n                            description: What host IP to bind the external port to.\n                            type: string\n                          hostPort:\n                            description: |-\n                              Number of port to expose on the host.\n                              If specified, this must be a valid port number, 0 < x < 65536.\n                              If HostNetwork is specified, this must match ContainerPort.\n                              Most containers do not need this.\n                            format: int32\n                            type: integer\n                          name:\n                            description: |-\n                              If specified, this must be an IANA_SVC_NAME and unique within the pod. Each\n                              named port in a pod must have a unique name. Name for the port that can be\n                              referred to by services.\n                            type: string\n                          protocol:\n                            default: TCP\n                            description: |-\n                              Protocol for port. Must be UDP, TCP, or SCTP.\n                              Defaults to \"TCP\".\n                            type: string\n                        required:\n                        - containerPort\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - containerPort\n                      - protocol\n                      x-kubernetes-list-type: map\n                    readinessProbe:\n                      description: |-\n                        Periodic probe of container service readiness.\n                        Container will be removed from service endpoints if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    resizePolicy:\n                      description: Resources resize policy for the container.\n                      items:\n                        description: ContainerResizePolicy represents resource resize policy for the container.\n                        properties:\n                          resourceName:\n                            description: |-\n                              Name of the resource to which this resource resize policy applies.\n                              Supported values: cpu, memory.\n                            type: string\n                          restartPolicy:\n                            description: |-\n                              Restart policy to apply when specified resource is resized.\n                              If not specified, it defaults to NotRequired.\n                            type: string\n                        required:\n                        - resourceName\n                        - restartPolicy\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    resources:\n                      description: |-\n                        Compute Resources required by this container.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                      properties:\n                        claims:\n                          description: |-\n                            Claims lists the names of resources, defined in spec.resourceClaims,\n                            that are used by this container.\n\n                            This is an alpha field and requires enabling the\n                            DynamicResourceAllocation feature gate.\n\n                            This field is immutable. It can only be set for containers.\n                          items:\n                            description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                            properties:\n                              name:\n                                description: |-\n                                  Name must match the name of one entry in pod.spec.resourceClaims of\n                                  the Pod where this field is used. It makes that resource available\n                                  inside a container.\n                                type: string\n                              request:\n                                description: |-\n                                  Request is the name chosen for a request in the referenced claim.\n                                  If empty, everything from the claim is made available, otherwise\n                                  only the result of this request.\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          type: array\n                          x-kubernetes-list-map-keys:\n                          - name\n                          x-kubernetes-list-type: map\n                        limits:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Limits describes the maximum amount of compute resources allowed.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                        requests:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Requests describes the minimum amount of compute resources required.\n                            If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                            otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                      type: object\n                    restartPolicy:\n                      description: |-\n                        RestartPolicy defines the restart behavior of individual containers in a pod.\n                        This field may only be set for init containers, and the only allowed value is \"Always\".\n                        For non-init containers or when this field is not specified,\n                        the restart behavior is defined by the Pod's restart policy and the container type.\n                        Setting the RestartPolicy as \"Always\" for the init container will have the following effect:\n                        this init container will be continually restarted on\n                        exit until all regular containers have terminated. Once all regular\n                        containers have completed, all init containers with restartPolicy \"Always\"\n                        will be shut down. This lifecycle differs from normal init containers and\n                        is often referred to as a \"sidecar\" container. Although this init\n                        container still starts in the init container sequence, it does not wait\n                        for the container to complete before proceeding to the next init\n                        container. Instead, the next init container starts immediately after this\n                        init container is started, or after any startupProbe has successfully\n                        completed.\n                      type: string\n                    securityContext:\n                      description: |-\n                        SecurityContext defines the security options the container should be run with.\n                        If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.\n                        More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/\n                      properties:\n                        allowPrivilegeEscalation:\n                          description: |-\n                            AllowPrivilegeEscalation controls whether a process can gain more\n                            privileges than its parent process. This bool directly controls if\n                            the no_new_privs flag will be set on the container process.\n                            AllowPrivilegeEscalation is true always when the container is:\n                            1) run as Privileged\n                            2) has CAP_SYS_ADMIN\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        appArmorProfile:\n                          description: |-\n                            appArmorProfile is the AppArmor options to use by this container. If set, this profile\n                            overrides the pod's appArmorProfile.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile loaded on the node that should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must match the loaded name of the profile.\n                                Must be set if and only if type is \"Localhost\".\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of AppArmor profile will be applied.\n                                Valid options are:\n                                  Localhost - a profile pre-loaded on the node.\n                                  RuntimeDefault - the container runtime's default profile.\n                                  Unconfined - no AppArmor enforcement.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        capabilities:\n                          description: |-\n                            The capabilities to add/drop when running containers.\n                            Defaults to the default set of capabilities granted by the container runtime.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            add:\n                              description: Added capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            drop:\n                              description: Removed capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        privileged:\n                          description: |-\n                            Run container in privileged mode.\n                            Processes in privileged containers are essentially equivalent to root on the host.\n                            Defaults to false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        procMount:\n                          description: |-\n                            procMount denotes the type of proc mount to use for the containers.\n                            The default value is Default which uses the container runtime defaults for\n                            readonly paths and masked paths.\n                            This requires the ProcMountType feature flag to be enabled.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: string\n                        readOnlyRootFilesystem:\n                          description: |-\n                            Whether this container has a read-only root filesystem.\n                            Default is false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        runAsGroup:\n                          description: |-\n                            The GID to run the entrypoint of the container process.\n                            Uses runtime default if unset.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        runAsNonRoot:\n                          description: |-\n                            Indicates that the container must run as a non-root user.\n                            If true, the Kubelet will validate the image at runtime to ensure that it\n                            does not run as UID 0 (root) and fail to start the container if it does.\n                            If unset or false, no such validation will be performed.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                          type: boolean\n                        runAsUser:\n                          description: |-\n                            The UID to run the entrypoint of the container process.\n                            Defaults to user specified in image metadata if unspecified.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        seLinuxOptions:\n                          description: |-\n                            The SELinux context to be applied to the container.\n                            If unspecified, the container runtime will allocate a random SELinux context for each\n                            container.  May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            level:\n                              description: Level is SELinux level label that applies to the container.\n                              type: string\n                            role:\n                              description: Role is a SELinux role label that applies to the container.\n                              type: string\n                            type:\n                              description: Type is a SELinux type label that applies to the container.\n                              type: string\n                            user:\n                              description: User is a SELinux user label that applies to the container.\n                              type: string\n                          type: object\n                        seccompProfile:\n                          description: |-\n                            The seccomp options to use by this container. If seccomp options are\n                            provided at both the pod & container level, the container options\n                            override the pod options.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile defined in a file on the node should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must be a descending path, relative to the kubelet's configured seccomp profile location.\n                                Must be set if type is \"Localhost\". Must NOT be set for any other type.\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of seccomp profile will be applied.\n                                Valid options are:\n\n                                Localhost - a profile defined in a file on the node should be used.\n                                RuntimeDefault - the container runtime default profile should be used.\n                                Unconfined - no profile should be applied.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        windowsOptions:\n                          description: |-\n                            The Windows specific settings applied to all containers.\n                            If unspecified, the options from the PodSecurityContext will be used.\n                            If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is linux.\n                          properties:\n                            gmsaCredentialSpec:\n                              description: |-\n                                GMSACredentialSpec is where the GMSA admission webhook\n                                (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the\n                                GMSA credential spec named by the GMSACredentialSpecName field.\n                              type: string\n                            gmsaCredentialSpecName:\n                              description: GMSACredentialSpecName is the name of the GMSA credential spec to use.\n                              type: string\n                            hostProcess:\n                              description: |-\n                                HostProcess determines if a container should be run as a 'Host Process' container.\n                                All of a Pod's containers must have the same effective HostProcess value\n                                (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).\n                                In addition, if HostProcess is true then HostNetwork must also be set to true.\n                              type: boolean\n                            runAsUserName:\n                              description: |-\n                                The UserName in Windows to run the entrypoint of the container process.\n                                Defaults to the user specified in image metadata if unspecified.\n                                May also be set in PodSecurityContext. If set in both SecurityContext and\n                                PodSecurityContext, the value specified in SecurityContext takes precedence.\n                              type: string\n                          type: object\n                      type: object\n                    startupProbe:\n                      description: |-\n                        StartupProbe indicates that the Pod has successfully initialized.\n                        If specified, no other probes are executed until this completes successfully.\n                        If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.\n                        This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,\n                        when it might take a long time to load data or warm a cache, than during steady-state operation.\n                        This cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    stdin:\n                      description: |-\n                        Whether this container should allocate a buffer for stdin in the container runtime. If this\n                        is not set, reads from stdin in the container will always result in EOF.\n                        Default is false.\n                      type: boolean\n                    stdinOnce:\n                      description: |-\n                        Whether the container runtime should close the stdin channel after it has been opened by\n                        a single attach. When stdin is true the stdin stream will remain open across multiple attach\n                        sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the\n                        first client attaches to stdin, and then remains open and accepts data until the client disconnects,\n                        at which time stdin is closed and remains closed until the container is restarted. If this\n                        flag is false, a container processes that reads from stdin will never receive an EOF.\n                        Default is false\n                      type: boolean\n                    terminationMessagePath:\n                      description: |-\n                        Optional: Path at which the file to which the container's termination message\n                        will be written is mounted into the container's filesystem.\n                        Message written is intended to be brief final status, such as an assertion failure message.\n                        Will be truncated by the node if greater than 4096 bytes. The total message length across\n                        all containers will be limited to 12kb.\n                        Defaults to /dev/termination-log.\n                        Cannot be updated.\n                      type: string\n                    terminationMessagePolicy:\n                      description: |-\n                        Indicate how the termination message should be populated. File will use the contents of\n                        terminationMessagePath to populate the container status message on both success and failure.\n                        FallbackToLogsOnError will use the last chunk of container log output if the termination\n                        message file is empty and the container exited with an error.\n                        The log output is limited to 2048 bytes or 80 lines, whichever is smaller.\n                        Defaults to File.\n                        Cannot be updated.\n                      type: string\n                    tty:\n                      description: |-\n                        Whether this container should allocate a TTY for itself, also requires 'stdin' to be true.\n                        Default is false.\n                      type: boolean\n                    volumeDevices:\n                      description: volumeDevices is the list of block devices to be used by the container.\n                      items:\n                        description: volumeDevice describes a mapping of a raw block device within a container.\n                        properties:\n                          devicePath:\n                            description: devicePath is the path inside of the container that the device will be mapped to.\n                            type: string\n                          name:\n                            description: name must match the name of a persistentVolumeClaim in the pod\n                            type: string\n                        required:\n                        - devicePath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - devicePath\n                      x-kubernetes-list-type: map\n                    volumeMounts:\n                      description: |-\n                        Pod volumes to mount into the container's filesystem.\n                        Cannot be updated.\n                      items:\n                        description: VolumeMount describes a mounting of a Volume within a container.\n                        properties:\n                          mountPath:\n                            description: |-\n                              Path within the container at which the volume should be mounted.  Must\n                              not contain ':'.\n                            type: string\n                          mountPropagation:\n                            description: |-\n                              mountPropagation determines how mounts are propagated from the host\n                              to container and the other way around.\n                              When not set, MountPropagationNone is used.\n                              This field is beta in 1.10.\n                              When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                              (which defaults to None).\n                            type: string\n                          name:\n                            description: This must match the Name of a Volume.\n                            type: string\n                          readOnly:\n                            description: |-\n                              Mounted read-only if true, read-write otherwise (false or unspecified).\n                              Defaults to false.\n                            type: boolean\n                          recursiveReadOnly:\n                            description: |-\n                              RecursiveReadOnly specifies whether read-only mounts should be handled\n                              recursively.\n\n                              If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                              If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                              recursively read-only.  If this field is set to IfPossible, the mount is made\n                              recursively read-only, if it is supported by the container runtime.  If this\n                              field is set to Enabled, the mount is made recursively read-only if it is\n                              supported by the container runtime, otherwise the pod will not be started and\n                              an error will be generated to indicate the reason.\n\n                              If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                              None (or be unspecified, which defaults to None).\n\n                              If this field is not specified, it is treated as an equivalent of Disabled.\n                            type: string\n                          subPath:\n                            description: |-\n                              Path within the volume from which the container's volume should be mounted.\n                              Defaults to \"\" (volume's root).\n                            type: string\n                          subPathExpr:\n                            description: |-\n                              Expanded path within the volume from which the container's volume should be mounted.\n                              Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                              Defaults to \"\" (volume's root).\n                              SubPathExpr and SubPath are mutually exclusive.\n                            type: string\n                        required:\n                        - mountPath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - mountPath\n                      x-kubernetes-list-type: map\n                    workingDir:\n                      description: |-\n                        Container's working directory.\n                        If not specified, the container runtime's default will be used, which\n                        might be configured in the container image.\n                        Cannot be updated.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                type: array\n              convertClassicHistogramsToNHCB:\n                description: |-\n                  Whether to convert all scraped classic histograms into a native\n                  histogram with custom buckets.\n\n                  It requires Prometheus >= v3.4.0.\n                type: boolean\n              disableCompaction:\n                description: |-\n                  When true, the Prometheus compaction is disabled.\n                  When `spec.thanos.objectStorageConfig` or `spec.objectStorageConfigFile` are defined, the operator automatically\n                  disables block compaction to avoid race conditions during block uploads (as the Thanos documentation recommends).\n                type: boolean\n              dnsConfig:\n                description: Defines the DNS configuration for the pods.\n                properties:\n                  nameservers:\n                    description: |-\n                      A list of DNS name server IP addresses.\n                      This will be appended to the base nameservers generated from DNSPolicy.\n                    items:\n                      minLength: 1\n                      type: string\n                    type: array\n                    x-kubernetes-list-type: set\n                  options:\n                    description: |-\n                      A list of DNS resolver options.\n                      This will be merged with the base options generated from DNSPolicy.\n                      Resolution options given in Options\n                      will override those that appear in the base DNSPolicy.\n                    items:\n                      description: PodDNSConfigOption defines DNS resolver options of a pod.\n                      properties:\n                        name:\n                          description: Name is required and must be unique.\n                          minLength: 1\n                          type: string\n                        value:\n                          description: Value is optional.\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    type: array\n                    x-kubernetes-list-map-keys:\n                    - name\n                    x-kubernetes-list-type: map\n                  searches:\n                    description: |-\n                      A list of DNS search domains for host-name lookup.\n                      This will be appended to the base search paths generated from DNSPolicy.\n                    items:\n                      minLength: 1\n                      type: string\n                    type: array\n                    x-kubernetes-list-type: set\n                type: object\n              dnsPolicy:\n                description: Defines the DNS policy for the pods.\n                enum:\n                - ClusterFirstWithHostNet\n                - ClusterFirst\n                - Default\n                - None\n                type: string\n              enableAdminAPI:\n                description: |-\n                  Enables access to the Prometheus web admin API.\n\n                  WARNING: Enabling the admin APIs enables mutating endpoints, to delete data,\n                  shutdown Prometheus, and more. Enabling this should be done with care and the\n                  user is advised to add additional authentication authorization via a proxy to\n                  ensure only clients authorized to perform these actions can do so.\n\n                  For more information:\n                  https://prometheus.io/docs/prometheus/latest/querying/api/#tsdb-admin-apis\n                type: boolean\n              enableFeatures:\n                description: |-\n                  Enable access to Prometheus feature flags. By default, no features are enabled.\n\n                  Enabling features which are disabled by default is entirely outside the\n                  scope of what the maintainers will support and by doing so, you accept\n                  that this behaviour may break at any time without notice.\n\n                  For more information see https://prometheus.io/docs/prometheus/latest/feature_flags/\n                items:\n                  minLength: 1\n                  type: string\n                type: array\n                x-kubernetes-list-type: set\n              enableOTLPReceiver:\n                description: |-\n                  Enable Prometheus to be used as a receiver for the OTLP Metrics protocol.\n\n                  Note that the OTLP receiver endpoint is automatically enabled if `.spec.otlpConfig` is defined.\n\n                  It requires Prometheus >= v2.47.0.\n                type: boolean\n              enableRemoteWriteReceiver:\n                description: |-\n                  Enable Prometheus to be used as a receiver for the Prometheus remote\n                  write protocol.\n\n                  WARNING: This is not considered an efficient way of ingesting samples.\n                  Use it with caution for specific low-volume use cases.\n                  It is not suitable for replacing the ingestion via scraping and turning\n                  Prometheus into a push-based metrics collection system.\n                  For more information see https://prometheus.io/docs/prometheus/latest/querying/api/#remote-write-receiver\n\n                  It requires Prometheus >= v2.33.0.\n                type: boolean\n              enableServiceLinks:\n                description: Indicates whether information about services should be injected into pod's environment variables\n                type: boolean\n              enforcedBodySizeLimit:\n                description: |-\n                  When defined, enforcedBodySizeLimit specifies a global limit on the size\n                  of uncompressed response body that will be accepted by Prometheus.\n                  Targets responding with a body larger than this many bytes will cause\n                  the scrape to fail.\n\n                  It requires Prometheus >= v2.28.0.\n\n                  When both `enforcedBodySizeLimit` and `bodySizeLimit` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined bodySizeLimit value will inherit the global bodySizeLimit value (Prometheus >= 2.45.0) or the enforcedBodySizeLimit value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedBodySizeLimit` is greater than the `bodySizeLimit`, the `bodySizeLimit` will be set to `enforcedBodySizeLimit`.\n                  * Scrape objects with a bodySizeLimit value less than or equal to enforcedBodySizeLimit keep their specific value.\n                  * Scrape objects with a bodySizeLimit value greater than enforcedBodySizeLimit are set to enforcedBodySizeLimit.\n                pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$\n                type: string\n              enforcedKeepDroppedTargets:\n                description: |-\n                  When defined, enforcedKeepDroppedTargets specifies a global limit on the number of targets\n                  dropped by relabeling that will be kept in memory. The value overrides\n                  any `spec.keepDroppedTargets` set by\n                  ServiceMonitor, PodMonitor, Probe objects unless `spec.keepDroppedTargets` is\n                  greater than zero and less than `spec.enforcedKeepDroppedTargets`.\n\n                  It requires Prometheus >= v2.47.0.\n\n                  When both `enforcedKeepDroppedTargets` and `keepDroppedTargets` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined keepDroppedTargets value will inherit the global keepDroppedTargets value (Prometheus >= 2.45.0) or the enforcedKeepDroppedTargets value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedKeepDroppedTargets` is greater than the `keepDroppedTargets`, the `keepDroppedTargets` will be set to `enforcedKeepDroppedTargets`.\n                  * Scrape objects with a keepDroppedTargets value less than or equal to enforcedKeepDroppedTargets keep their specific value.\n                  * Scrape objects with a keepDroppedTargets value greater than enforcedKeepDroppedTargets are set to enforcedKeepDroppedTargets.\n                format: int64\n                type: integer\n              enforcedLabelLimit:\n                description: |-\n                  When defined, enforcedLabelLimit specifies a global limit on the number\n                  of labels per sample. The value overrides any `spec.labelLimit` set by\n                  ServiceMonitor, PodMonitor, Probe objects unless `spec.labelLimit` is\n                  greater than zero and less than `spec.enforcedLabelLimit`.\n\n                  It requires Prometheus >= v2.27.0.\n\n                  When both `enforcedLabelLimit` and `labelLimit` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined labelLimit value will inherit the global labelLimit value (Prometheus >= 2.45.0) or the enforcedLabelLimit value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedLabelLimit` is greater than the `labelLimit`, the `labelLimit` will be set to `enforcedLabelLimit`.\n                  * Scrape objects with a labelLimit value less than or equal to enforcedLabelLimit keep their specific value.\n                  * Scrape objects with a labelLimit value greater than enforcedLabelLimit are set to enforcedLabelLimit.\n                format: int64\n                type: integer\n              enforcedLabelNameLengthLimit:\n                description: |-\n                  When defined, enforcedLabelNameLengthLimit specifies a global limit on the length\n                  of labels name per sample. The value overrides any `spec.labelNameLengthLimit` set by\n                  ServiceMonitor, PodMonitor, Probe objects unless `spec.labelNameLengthLimit` is\n                  greater than zero and less than `spec.enforcedLabelNameLengthLimit`.\n\n                  It requires Prometheus >= v2.27.0.\n\n                  When both `enforcedLabelNameLengthLimit` and `labelNameLengthLimit` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined labelNameLengthLimit value will inherit the global labelNameLengthLimit value (Prometheus >= 2.45.0) or the enforcedLabelNameLengthLimit value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedLabelNameLengthLimit` is greater than the `labelNameLengthLimit`, the `labelNameLengthLimit` will be set to `enforcedLabelNameLengthLimit`.\n                  * Scrape objects with a labelNameLengthLimit value less than or equal to enforcedLabelNameLengthLimit keep their specific value.\n                  * Scrape objects with a labelNameLengthLimit value greater than enforcedLabelNameLengthLimit are set to enforcedLabelNameLengthLimit.\n                format: int64\n                type: integer\n              enforcedLabelValueLengthLimit:\n                description: |-\n                  When not null, enforcedLabelValueLengthLimit defines a global limit on the length\n                  of labels value per sample. The value overrides any `spec.labelValueLengthLimit` set by\n                  ServiceMonitor, PodMonitor, Probe objects unless `spec.labelValueLengthLimit` is\n                  greater than zero and less than `spec.enforcedLabelValueLengthLimit`.\n\n                  It requires Prometheus >= v2.27.0.\n\n                  When both `enforcedLabelValueLengthLimit` and `labelValueLengthLimit` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined labelValueLengthLimit value will inherit the global labelValueLengthLimit value (Prometheus >= 2.45.0) or the enforcedLabelValueLengthLimit value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedLabelValueLengthLimit` is greater than the `labelValueLengthLimit`, the `labelValueLengthLimit` will be set to `enforcedLabelValueLengthLimit`.\n                  * Scrape objects with a labelValueLengthLimit value less than or equal to enforcedLabelValueLengthLimit keep their specific value.\n                  * Scrape objects with a labelValueLengthLimit value greater than enforcedLabelValueLengthLimit are set to enforcedLabelValueLengthLimit.\n                format: int64\n                type: integer\n              enforcedNamespaceLabel:\n                description: |-\n                  When not empty, a label will be added to:\n\n                  1. All metrics scraped from `ServiceMonitor`, `PodMonitor`, `Probe` and `ScrapeConfig` objects.\n                  2. All metrics generated from recording rules defined in `PrometheusRule` objects.\n                  3. All alerts generated from alerting rules defined in `PrometheusRule` objects.\n                  4. All vector selectors of PromQL expressions defined in `PrometheusRule` objects.\n\n                  The label will not added for objects referenced in `spec.excludedFromEnforcement`.\n\n                  The label's name is this field's value.\n                  The label's value is the namespace of the `ServiceMonitor`,\n                  `PodMonitor`, `Probe`, `PrometheusRule` or `ScrapeConfig` object.\n                type: string\n              enforcedSampleLimit:\n                description: |-\n                  When defined, enforcedSampleLimit specifies a global limit on the number\n                  of scraped samples that will be accepted. This overrides any\n                  `spec.sampleLimit` set by ServiceMonitor, PodMonitor, Probe objects\n                  unless `spec.sampleLimit` is greater than zero and less than\n                  `spec.enforcedSampleLimit`.\n\n                  It is meant to be used by admins to keep the overall number of\n                  samples/series under a desired limit.\n\n                  When both `enforcedSampleLimit` and `sampleLimit` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined sampleLimit value will inherit the global sampleLimit value (Prometheus >= 2.45.0) or the enforcedSampleLimit value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedSampleLimit` is greater than the `sampleLimit`, the `sampleLimit` will be set to `enforcedSampleLimit`.\n                  * Scrape objects with a sampleLimit value less than or equal to enforcedSampleLimit keep their specific value.\n                  * Scrape objects with a sampleLimit value greater than enforcedSampleLimit are set to enforcedSampleLimit.\n                format: int64\n                type: integer\n              enforcedTargetLimit:\n                description: |-\n                  When defined, enforcedTargetLimit specifies a global limit on the number\n                  of scraped targets. The value overrides any `spec.targetLimit` set by\n                  ServiceMonitor, PodMonitor, Probe objects unless `spec.targetLimit` is\n                  greater than zero and less than `spec.enforcedTargetLimit`.\n\n                  It is meant to be used by admins to to keep the overall number of\n                  targets under a desired limit.\n\n                  When both `enforcedTargetLimit` and `targetLimit` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined targetLimit value will inherit the global targetLimit value (Prometheus >= 2.45.0) or the enforcedTargetLimit value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedTargetLimit` is greater than the `targetLimit`, the `targetLimit` will be set to `enforcedTargetLimit`.\n                  * Scrape objects with a targetLimit value less than or equal to enforcedTargetLimit keep their specific value.\n                  * Scrape objects with a targetLimit value greater than enforcedTargetLimit are set to enforcedTargetLimit.\n                format: int64\n                type: integer\n              evaluationInterval:\n                default: 30s\n                description: |-\n                  Interval between rule evaluations.\n                  Default: \"30s\"\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              excludedFromEnforcement:\n                description: |-\n                  List of references to PodMonitor, ServiceMonitor, Probe and PrometheusRule objects\n                  to be excluded from enforcing a namespace label of origin.\n\n                  It is only applicable if `spec.enforcedNamespaceLabel` set to true.\n                items:\n                  description: ObjectReference references a PodMonitor, ServiceMonitor, Probe or PrometheusRule object.\n                  properties:\n                    group:\n                      default: monitoring.coreos.com\n                      description: Group of the referent. When not specified, it defaults to `monitoring.coreos.com`\n                      enum:\n                      - monitoring.coreos.com\n                      type: string\n                    name:\n                      description: Name of the referent. When not set, all resources in the namespace are matched.\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace of the referent.\n                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/\n                      minLength: 1\n                      type: string\n                    resource:\n                      description: Resource of the referent.\n                      enum:\n                      - prometheusrules\n                      - servicemonitors\n                      - podmonitors\n                      - probes\n                      - scrapeconfigs\n                      type: string\n                  required:\n                  - namespace\n                  - resource\n                  type: object\n                type: array\n              exemplars:\n                description: |-\n                  Exemplars related settings that are runtime reloadable.\n                  It requires to enable the `exemplar-storage` feature flag to be effective.\n                properties:\n                  maxSize:\n                    description: |-\n                      Maximum number of exemplars stored in memory for all series.\n\n                      exemplar-storage itself must be enabled using the `spec.enableFeature`\n                      option for exemplars to be scraped in the first place.\n\n                      If not set, Prometheus uses its default value. A value of zero or less\n                      than zero disables the storage.\n                    format: int64\n                    type: integer\n                type: object\n              externalLabels:\n                additionalProperties:\n                  type: string\n                description: |-\n                  The labels to add to any time series or alerts when communicating with\n                  external systems (federation, remote storage, Alertmanager).\n                  Labels defined by `spec.replicaExternalLabelName` and\n                  `spec.prometheusExternalLabelName` take precedence over this list.\n                type: object\n              externalUrl:\n                description: |-\n                  The external URL under which the Prometheus service is externally\n                  available. This is necessary to generate correct URLs (for instance if\n                  Prometheus is accessible behind an Ingress resource).\n                type: string\n              hostAliases:\n                description: |-\n                  Optional list of hosts and IPs that will be injected into the Pod's\n                  hosts file if specified.\n                items:\n                  description: |-\n                    HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the\n                    pod's hosts file.\n                  properties:\n                    hostnames:\n                      description: Hostnames for the above IP address.\n                      items:\n                        type: string\n                      type: array\n                    ip:\n                      description: IP address of the host file entry.\n                      type: string\n                  required:\n                  - hostnames\n                  - ip\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - ip\n                x-kubernetes-list-type: map\n              hostNetwork:\n                description: |-\n                  Use the host's network namespace if true.\n\n                  Make sure to understand the security implications if you want to enable\n                  it (https://kubernetes.io/docs/concepts/configuration/overview/ ).\n\n                  When hostNetwork is enabled, this will set the DNS policy to\n                  `ClusterFirstWithHostNet` automatically (unless `.spec.DNSPolicy` is set\n                  to a different value).\n                type: boolean\n              hostUsers:\n                description: |-\n                  HostUsers supports the user space in Kubernetes.\n\n                  More info: https://kubernetes.io/docs/tasks/configure-pod-container/user-namespaces/\n\n                  The feature requires at least Kubernetes 1.28 with the `UserNamespacesSupport` feature gate enabled.\n                  Starting Kubernetes 1.33, the feature is enabled by default.\n                type: boolean\n              ignoreNamespaceSelectors:\n                description: |-\n                  When true, `spec.namespaceSelector` from all PodMonitor, ServiceMonitor\n                  and Probe objects will be ignored. They will only discover targets\n                  within the namespace of the PodMonitor, ServiceMonitor and Probe\n                  object.\n                type: boolean\n              image:\n                description: |-\n                  Container image name for Prometheus. If specified, it takes precedence\n                  over the `spec.baseImage`, `spec.tag` and `spec.sha` fields.\n\n                  Specifying `spec.version` is still necessary to ensure the Prometheus\n                  Operator knows which version of Prometheus is being configured.\n\n                  If neither `spec.image` nor `spec.baseImage` are defined, the operator\n                  will use the latest upstream version of Prometheus available at the time\n                  when the operator was released.\n                type: string\n              imagePullPolicy:\n                description: |-\n                  Image pull policy for the 'prometheus', 'init-config-reloader' and 'config-reloader' containers.\n                  See https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy for more details.\n                enum:\n                - \"\"\n                - Always\n                - Never\n                - IfNotPresent\n                type: string\n              imagePullSecrets:\n                description: |-\n                  An optional list of references to Secrets in the same namespace\n                  to use for pulling images from registries.\n                  See http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod\n                items:\n                  description: |-\n                    LocalObjectReference contains enough information to let you locate the\n                    referenced object inside the same namespace.\n                  properties:\n                    name:\n                      default: \"\"\n                      description: |-\n                        Name of the referent.\n                        This field is effectively required, but due to backwards compatibility is\n                        allowed to be empty. Instances of this type with an empty value here are\n                        almost certainly wrong.\n                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                      type: string\n                  type: object\n                  x-kubernetes-map-type: atomic\n                type: array\n              initContainers:\n                description: |-\n                  InitContainers allows injecting initContainers to the Pod definition. Those\n                  can be used to e.g.  fetch secrets for injection into the Prometheus\n                  configuration from external sources. Any errors during the execution of\n                  an initContainer will lead to a restart of the Pod. More info:\n                  https://kubernetes.io/docs/concepts/workloads/pods/init-containers/\n                  InitContainers described here modify an operator generated init\n                  containers if they share the same name and modifications are done via a\n                  strategic merge patch.\n\n                  The names of init container name managed by the operator are:\n                  * `init-config-reloader`.\n\n                  Overriding init containers is entirely outside the scope of what the\n                  maintainers will support and by doing so, you accept that this behaviour\n                  may break at any time without notice.\n                items:\n                  description: A single application container that you want to run within a pod.\n                  properties:\n                    args:\n                      description: |-\n                        Arguments to the entrypoint.\n                        The container image's CMD is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    command:\n                      description: |-\n                        Entrypoint array. Not executed within a shell.\n                        The container image's ENTRYPOINT is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    env:\n                      description: |-\n                        List of environment variables to set in the container.\n                        Cannot be updated.\n                      items:\n                        description: EnvVar represents an environment variable present in a Container.\n                        properties:\n                          name:\n                            description: Name of the environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          value:\n                            description: |-\n                              Variable references $(VAR_NAME) are expanded\n                              using the previously defined environment variables in the container and\n                              any service environment variables. If a variable cannot be resolved,\n                              the reference in the input string will be unchanged. Double $$ are reduced\n                              to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.\n                              \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\".\n                              Escaped references will never be expanded, regardless of whether the variable\n                              exists or not.\n                              Defaults to \"\".\n                            type: string\n                          valueFrom:\n                            description: Source for the environment variable's value. Cannot be used if value is not empty.\n                            properties:\n                              configMapKeyRef:\n                                description: Selects a key of a ConfigMap.\n                                properties:\n                                  key:\n                                    description: The key to select.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the ConfigMap or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              fieldRef:\n                                description: |-\n                                  Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,\n                                  spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.\n                                properties:\n                                  apiVersion:\n                                    description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                    type: string\n                                  fieldPath:\n                                    description: Path of the field to select in the specified API version.\n                                    type: string\n                                required:\n                                - fieldPath\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              resourceFieldRef:\n                                description: |-\n                                  Selects a resource of the container: only resources limits and requests\n                                  (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.\n                                properties:\n                                  containerName:\n                                    description: 'Container name: required for volumes, optional for env vars'\n                                    type: string\n                                  divisor:\n                                    anyOf:\n                                    - type: integer\n                                    - type: string\n                                    description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                    x-kubernetes-int-or-string: true\n                                  resource:\n                                    description: 'Required: resource to select'\n                                    type: string\n                                required:\n                                - resource\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              secretKeyRef:\n                                description: Selects a key of a secret in the pod's namespace\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            type: object\n                        required:\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - name\n                      x-kubernetes-list-type: map\n                    envFrom:\n                      description: |-\n                        List of sources to populate environment variables in the container.\n                        The keys defined within a source must be a C_IDENTIFIER. All invalid keys\n                        will be reported as an event when the container is starting. When a key exists in multiple\n                        sources, the value associated with the last source will take precedence.\n                        Values defined by an Env with a duplicate key will take precedence.\n                        Cannot be updated.\n                      items:\n                        description: EnvFromSource represents the source of a set of ConfigMaps or Secrets\n                        properties:\n                          configMapRef:\n                            description: The ConfigMap to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          prefix:\n                            description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          secretRef:\n                            description: The Secret to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    image:\n                      description: |-\n                        Container image name.\n                        More info: https://kubernetes.io/docs/concepts/containers/images\n                        This field is optional to allow higher level config management to default or override\n                        container images in workload controllers like Deployments and StatefulSets.\n                      type: string\n                    imagePullPolicy:\n                      description: |-\n                        Image pull policy.\n                        One of Always, Never, IfNotPresent.\n                        Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/containers/images#updating-images\n                      type: string\n                    lifecycle:\n                      description: |-\n                        Actions that the management system should take in response to container lifecycle events.\n                        Cannot be updated.\n                      properties:\n                        postStart:\n                          description: |-\n                            PostStart is called immediately after a container is created. If the handler fails,\n                            the container is terminated and restarted according to its restart policy.\n                            Other management of the container blocks until the hook completes.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        preStop:\n                          description: |-\n                            PreStop is called immediately before a container is terminated due to an\n                            API request or management event such as liveness/startup probe failure,\n                            preemption, resource contention, etc. The handler is not called if the\n                            container crashes or exits. The Pod's termination grace period countdown begins before the\n                            PreStop hook is executed. Regardless of the outcome of the handler, the\n                            container will eventually terminate within the Pod's termination grace\n                            period (unless delayed by finalizers). Other management of the container blocks until the hook completes\n                            or until the termination grace period is reached.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        stopSignal:\n                          description: |-\n                            StopSignal defines which signal will be sent to a container when it is being stopped.\n                            If not specified, the default is defined by the container runtime in use.\n                            StopSignal can only be set for Pods with a non-empty .spec.os.name\n                          type: string\n                      type: object\n                    livenessProbe:\n                      description: |-\n                        Periodic probe of container liveness.\n                        Container will be restarted if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    name:\n                      description: |-\n                        Name of the container specified as a DNS_LABEL.\n                        Each container in a pod must have a unique name (DNS_LABEL).\n                        Cannot be updated.\n                      type: string\n                    ports:\n                      description: |-\n                        List of ports to expose from the container. Not specifying a port here\n                        DOES NOT prevent that port from being exposed. Any port which is\n                        listening on the default \"0.0.0.0\" address inside a container will be\n                        accessible from the network.\n                        Modifying this array with strategic merge patch may corrupt the data.\n                        For more information See https://github.com/kubernetes/kubernetes/issues/108255.\n                        Cannot be updated.\n                      items:\n                        description: ContainerPort represents a network port in a single container.\n                        properties:\n                          containerPort:\n                            description: |-\n                              Number of port to expose on the pod's IP address.\n                              This must be a valid port number, 0 < x < 65536.\n                            format: int32\n                            type: integer\n                          hostIP:\n                            description: What host IP to bind the external port to.\n                            type: string\n                          hostPort:\n                            description: |-\n                              Number of port to expose on the host.\n                              If specified, this must be a valid port number, 0 < x < 65536.\n                              If HostNetwork is specified, this must match ContainerPort.\n                              Most containers do not need this.\n                            format: int32\n                            type: integer\n                          name:\n                            description: |-\n                              If specified, this must be an IANA_SVC_NAME and unique within the pod. Each\n                              named port in a pod must have a unique name. Name for the port that can be\n                              referred to by services.\n                            type: string\n                          protocol:\n                            default: TCP\n                            description: |-\n                              Protocol for port. Must be UDP, TCP, or SCTP.\n                              Defaults to \"TCP\".\n                            type: string\n                        required:\n                        - containerPort\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - containerPort\n                      - protocol\n                      x-kubernetes-list-type: map\n                    readinessProbe:\n                      description: |-\n                        Periodic probe of container service readiness.\n                        Container will be removed from service endpoints if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    resizePolicy:\n                      description: Resources resize policy for the container.\n                      items:\n                        description: ContainerResizePolicy represents resource resize policy for the container.\n                        properties:\n                          resourceName:\n                            description: |-\n                              Name of the resource to which this resource resize policy applies.\n                              Supported values: cpu, memory.\n                            type: string\n                          restartPolicy:\n                            description: |-\n                              Restart policy to apply when specified resource is resized.\n                              If not specified, it defaults to NotRequired.\n                            type: string\n                        required:\n                        - resourceName\n                        - restartPolicy\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    resources:\n                      description: |-\n                        Compute Resources required by this container.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                      properties:\n                        claims:\n                          description: |-\n                            Claims lists the names of resources, defined in spec.resourceClaims,\n                            that are used by this container.\n\n                            This is an alpha field and requires enabling the\n                            DynamicResourceAllocation feature gate.\n\n                            This field is immutable. It can only be set for containers.\n                          items:\n                            description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                            properties:\n                              name:\n                                description: |-\n                                  Name must match the name of one entry in pod.spec.resourceClaims of\n                                  the Pod where this field is used. It makes that resource available\n                                  inside a container.\n                                type: string\n                              request:\n                                description: |-\n                                  Request is the name chosen for a request in the referenced claim.\n                                  If empty, everything from the claim is made available, otherwise\n                                  only the result of this request.\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          type: array\n                          x-kubernetes-list-map-keys:\n                          - name\n                          x-kubernetes-list-type: map\n                        limits:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Limits describes the maximum amount of compute resources allowed.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                        requests:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Requests describes the minimum amount of compute resources required.\n                            If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                            otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                      type: object\n                    restartPolicy:\n                      description: |-\n                        RestartPolicy defines the restart behavior of individual containers in a pod.\n                        This field may only be set for init containers, and the only allowed value is \"Always\".\n                        For non-init containers or when this field is not specified,\n                        the restart behavior is defined by the Pod's restart policy and the container type.\n                        Setting the RestartPolicy as \"Always\" for the init container will have the following effect:\n                        this init container will be continually restarted on\n                        exit until all regular containers have terminated. Once all regular\n                        containers have completed, all init containers with restartPolicy \"Always\"\n                        will be shut down. This lifecycle differs from normal init containers and\n                        is often referred to as a \"sidecar\" container. Although this init\n                        container still starts in the init container sequence, it does not wait\n                        for the container to complete before proceeding to the next init\n                        container. Instead, the next init container starts immediately after this\n                        init container is started, or after any startupProbe has successfully\n                        completed.\n                      type: string\n                    securityContext:\n                      description: |-\n                        SecurityContext defines the security options the container should be run with.\n                        If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.\n                        More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/\n                      properties:\n                        allowPrivilegeEscalation:\n                          description: |-\n                            AllowPrivilegeEscalation controls whether a process can gain more\n                            privileges than its parent process. This bool directly controls if\n                            the no_new_privs flag will be set on the container process.\n                            AllowPrivilegeEscalation is true always when the container is:\n                            1) run as Privileged\n                            2) has CAP_SYS_ADMIN\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        appArmorProfile:\n                          description: |-\n                            appArmorProfile is the AppArmor options to use by this container. If set, this profile\n                            overrides the pod's appArmorProfile.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile loaded on the node that should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must match the loaded name of the profile.\n                                Must be set if and only if type is \"Localhost\".\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of AppArmor profile will be applied.\n                                Valid options are:\n                                  Localhost - a profile pre-loaded on the node.\n                                  RuntimeDefault - the container runtime's default profile.\n                                  Unconfined - no AppArmor enforcement.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        capabilities:\n                          description: |-\n                            The capabilities to add/drop when running containers.\n                            Defaults to the default set of capabilities granted by the container runtime.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            add:\n                              description: Added capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            drop:\n                              description: Removed capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        privileged:\n                          description: |-\n                            Run container in privileged mode.\n                            Processes in privileged containers are essentially equivalent to root on the host.\n                            Defaults to false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        procMount:\n                          description: |-\n                            procMount denotes the type of proc mount to use for the containers.\n                            The default value is Default which uses the container runtime defaults for\n                            readonly paths and masked paths.\n                            This requires the ProcMountType feature flag to be enabled.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: string\n                        readOnlyRootFilesystem:\n                          description: |-\n                            Whether this container has a read-only root filesystem.\n                            Default is false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        runAsGroup:\n                          description: |-\n                            The GID to run the entrypoint of the container process.\n                            Uses runtime default if unset.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        runAsNonRoot:\n                          description: |-\n                            Indicates that the container must run as a non-root user.\n                            If true, the Kubelet will validate the image at runtime to ensure that it\n                            does not run as UID 0 (root) and fail to start the container if it does.\n                            If unset or false, no such validation will be performed.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                          type: boolean\n                        runAsUser:\n                          description: |-\n                            The UID to run the entrypoint of the container process.\n                            Defaults to user specified in image metadata if unspecified.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        seLinuxOptions:\n                          description: |-\n                            The SELinux context to be applied to the container.\n                            If unspecified, the container runtime will allocate a random SELinux context for each\n                            container.  May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            level:\n                              description: Level is SELinux level label that applies to the container.\n                              type: string\n                            role:\n                              description: Role is a SELinux role label that applies to the container.\n                              type: string\n                            type:\n                              description: Type is a SELinux type label that applies to the container.\n                              type: string\n                            user:\n                              description: User is a SELinux user label that applies to the container.\n                              type: string\n                          type: object\n                        seccompProfile:\n                          description: |-\n                            The seccomp options to use by this container. If seccomp options are\n                            provided at both the pod & container level, the container options\n                            override the pod options.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile defined in a file on the node should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must be a descending path, relative to the kubelet's configured seccomp profile location.\n                                Must be set if type is \"Localhost\". Must NOT be set for any other type.\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of seccomp profile will be applied.\n                                Valid options are:\n\n                                Localhost - a profile defined in a file on the node should be used.\n                                RuntimeDefault - the container runtime default profile should be used.\n                                Unconfined - no profile should be applied.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        windowsOptions:\n                          description: |-\n                            The Windows specific settings applied to all containers.\n                            If unspecified, the options from the PodSecurityContext will be used.\n                            If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is linux.\n                          properties:\n                            gmsaCredentialSpec:\n                              description: |-\n                                GMSACredentialSpec is where the GMSA admission webhook\n                                (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the\n                                GMSA credential spec named by the GMSACredentialSpecName field.\n                              type: string\n                            gmsaCredentialSpecName:\n                              description: GMSACredentialSpecName is the name of the GMSA credential spec to use.\n                              type: string\n                            hostProcess:\n                              description: |-\n                                HostProcess determines if a container should be run as a 'Host Process' container.\n                                All of a Pod's containers must have the same effective HostProcess value\n                                (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).\n                                In addition, if HostProcess is true then HostNetwork must also be set to true.\n                              type: boolean\n                            runAsUserName:\n                              description: |-\n                                The UserName in Windows to run the entrypoint of the container process.\n                                Defaults to the user specified in image metadata if unspecified.\n                                May also be set in PodSecurityContext. If set in both SecurityContext and\n                                PodSecurityContext, the value specified in SecurityContext takes precedence.\n                              type: string\n                          type: object\n                      type: object\n                    startupProbe:\n                      description: |-\n                        StartupProbe indicates that the Pod has successfully initialized.\n                        If specified, no other probes are executed until this completes successfully.\n                        If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.\n                        This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,\n                        when it might take a long time to load data or warm a cache, than during steady-state operation.\n                        This cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    stdin:\n                      description: |-\n                        Whether this container should allocate a buffer for stdin in the container runtime. If this\n                        is not set, reads from stdin in the container will always result in EOF.\n                        Default is false.\n                      type: boolean\n                    stdinOnce:\n                      description: |-\n                        Whether the container runtime should close the stdin channel after it has been opened by\n                        a single attach. When stdin is true the stdin stream will remain open across multiple attach\n                        sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the\n                        first client attaches to stdin, and then remains open and accepts data until the client disconnects,\n                        at which time stdin is closed and remains closed until the container is restarted. If this\n                        flag is false, a container processes that reads from stdin will never receive an EOF.\n                        Default is false\n                      type: boolean\n                    terminationMessagePath:\n                      description: |-\n                        Optional: Path at which the file to which the container's termination message\n                        will be written is mounted into the container's filesystem.\n                        Message written is intended to be brief final status, such as an assertion failure message.\n                        Will be truncated by the node if greater than 4096 bytes. The total message length across\n                        all containers will be limited to 12kb.\n                        Defaults to /dev/termination-log.\n                        Cannot be updated.\n                      type: string\n                    terminationMessagePolicy:\n                      description: |-\n                        Indicate how the termination message should be populated. File will use the contents of\n                        terminationMessagePath to populate the container status message on both success and failure.\n                        FallbackToLogsOnError will use the last chunk of container log output if the termination\n                        message file is empty and the container exited with an error.\n                        The log output is limited to 2048 bytes or 80 lines, whichever is smaller.\n                        Defaults to File.\n                        Cannot be updated.\n                      type: string\n                    tty:\n                      description: |-\n                        Whether this container should allocate a TTY for itself, also requires 'stdin' to be true.\n                        Default is false.\n                      type: boolean\n                    volumeDevices:\n                      description: volumeDevices is the list of block devices to be used by the container.\n                      items:\n                        description: volumeDevice describes a mapping of a raw block device within a container.\n                        properties:\n                          devicePath:\n                            description: devicePath is the path inside of the container that the device will be mapped to.\n                            type: string\n                          name:\n                            description: name must match the name of a persistentVolumeClaim in the pod\n                            type: string\n                        required:\n                        - devicePath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - devicePath\n                      x-kubernetes-list-type: map\n                    volumeMounts:\n                      description: |-\n                        Pod volumes to mount into the container's filesystem.\n                        Cannot be updated.\n                      items:\n                        description: VolumeMount describes a mounting of a Volume within a container.\n                        properties:\n                          mountPath:\n                            description: |-\n                              Path within the container at which the volume should be mounted.  Must\n                              not contain ':'.\n                            type: string\n                          mountPropagation:\n                            description: |-\n                              mountPropagation determines how mounts are propagated from the host\n                              to container and the other way around.\n                              When not set, MountPropagationNone is used.\n                              This field is beta in 1.10.\n                              When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                              (which defaults to None).\n                            type: string\n                          name:\n                            description: This must match the Name of a Volume.\n                            type: string\n                          readOnly:\n                            description: |-\n                              Mounted read-only if true, read-write otherwise (false or unspecified).\n                              Defaults to false.\n                            type: boolean\n                          recursiveReadOnly:\n                            description: |-\n                              RecursiveReadOnly specifies whether read-only mounts should be handled\n                              recursively.\n\n                              If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                              If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                              recursively read-only.  If this field is set to IfPossible, the mount is made\n                              recursively read-only, if it is supported by the container runtime.  If this\n                              field is set to Enabled, the mount is made recursively read-only if it is\n                              supported by the container runtime, otherwise the pod will not be started and\n                              an error will be generated to indicate the reason.\n\n                              If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                              None (or be unspecified, which defaults to None).\n\n                              If this field is not specified, it is treated as an equivalent of Disabled.\n                            type: string\n                          subPath:\n                            description: |-\n                              Path within the volume from which the container's volume should be mounted.\n                              Defaults to \"\" (volume's root).\n                            type: string\n                          subPathExpr:\n                            description: |-\n                              Expanded path within the volume from which the container's volume should be mounted.\n                              Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                              Defaults to \"\" (volume's root).\n                              SubPathExpr and SubPath are mutually exclusive.\n                            type: string\n                        required:\n                        - mountPath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - mountPath\n                      x-kubernetes-list-type: map\n                    workingDir:\n                      description: |-\n                        Container's working directory.\n                        If not specified, the container runtime's default will be used, which\n                        might be configured in the container image.\n                        Cannot be updated.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                type: array\n              keepDroppedTargets:\n                description: |-\n                  Per-scrape limit on the number of targets dropped by relabeling\n                  that will be kept in memory. 0 means no limit.\n\n                  It requires Prometheus >= v2.47.0.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedKeepDroppedTargets.\n                format: int64\n                type: integer\n              labelLimit:\n                description: |-\n                  Per-scrape limit on number of labels that will be accepted for a sample.\n                  Only valid in Prometheus versions 2.45.0 and newer.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedLabelLimit.\n                format: int64\n                type: integer\n              labelNameLengthLimit:\n                description: |-\n                  Per-scrape limit on length of labels name that will be accepted for a sample.\n                  Only valid in Prometheus versions 2.45.0 and newer.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedLabelNameLengthLimit.\n                format: int64\n                type: integer\n              labelValueLengthLimit:\n                description: |-\n                  Per-scrape limit on length of labels value that will be accepted for a sample.\n                  Only valid in Prometheus versions 2.45.0 and newer.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedLabelValueLengthLimit.\n                format: int64\n                type: integer\n              listenLocal:\n                description: |-\n                  When true, the Prometheus server listens on the loopback address\n                  instead of the Pod IP's address.\n                type: boolean\n              logFormat:\n                description: Log format for Log level for Prometheus and the config-reloader sidecar.\n                enum:\n                - \"\"\n                - logfmt\n                - json\n                type: string\n              logLevel:\n                description: Log level for Prometheus and the config-reloader sidecar.\n                enum:\n                - \"\"\n                - debug\n                - info\n                - warn\n                - error\n                type: string\n              maximumStartupDurationSeconds:\n                description: |-\n                  Defines the maximum time that the `prometheus` container's startup probe will wait before being considered failed. The startup probe will return success after the WAL replay is complete.\n                  If set, the value should be greater than 60 (seconds). Otherwise it will be equal to 600 seconds (15 minutes).\n                format: int32\n                minimum: 60\n                type: integer\n              minReadySeconds:\n                description: |-\n                  Minimum number of seconds for which a newly created Pod should be ready\n                  without any of its container crashing for it to be considered available.\n\n                  If unset, pods will be considered available as soon as they are ready.\n                format: int32\n                minimum: 0\n                type: integer\n              nameEscapingScheme:\n                description: |-\n                  Specifies the character escaping scheme that will be requested when scraping\n                  for metric and label names that do not conform to the legacy Prometheus\n                  character set.\n\n                  It requires Prometheus >= v3.4.0.\n                enum:\n                - AllowUTF8\n                - Underscores\n                - Dots\n                - Values\n                type: string\n              nameValidationScheme:\n                description: |-\n                  Specifies the validation scheme for metric and label names.\n\n                  It requires Prometheus >= v2.55.0.\n                enum:\n                - UTF8\n                - Legacy\n                type: string\n              nodeSelector:\n                additionalProperties:\n                  type: string\n                description: Defines on which Nodes the Pods are scheduled.\n                type: object\n              otlp:\n                description: |-\n                  Settings related to the OTLP receiver feature.\n                  It requires Prometheus >= v2.55.0.\n                properties:\n                  convertHistogramsToNHCB:\n                    description: |-\n                      Configures optional translation of OTLP explicit bucket histograms into native histograms with custom buckets.\n                      It requires Prometheus >= v3.4.0.\n                    type: boolean\n                  ignoreResourceAttributes:\n                    description: |-\n                      List of OpenTelemetry resource attributes to ignore when `promoteAllResourceAttributes` is true.\n\n                      It requires `promoteAllResourceAttributes` to be true.\n                      It requires Prometheus >= v3.5.0.\n                    items:\n                      minLength: 1\n                      type: string\n                    minItems: 1\n                    type: array\n                    x-kubernetes-list-type: set\n                  keepIdentifyingResourceAttributes:\n                    description: |-\n                      Enables adding `service.name`, `service.namespace` and `service.instance.id`\n                      resource attributes to the `target_info` metric, on top of converting them into the `instance` and `job` labels.\n\n                      It requires Prometheus >= v3.1.0.\n                    type: boolean\n                  promoteAllResourceAttributes:\n                    description: |-\n                      Promote all resource attributes to metric labels except the ones defined in `ignoreResourceAttributes`.\n\n                      Cannot be true when `promoteResourceAttributes` is defined.\n                      It requires Prometheus >= v3.5.0.\n                    type: boolean\n                  promoteResourceAttributes:\n                    description: |-\n                      List of OpenTelemetry Attributes that should be promoted to metric labels, defaults to none.\n                      Cannot be defined when `promoteAllResourceAttributes` is true.\n                    items:\n                      minLength: 1\n                      type: string\n                    minItems: 1\n                    type: array\n                    x-kubernetes-list-type: set\n                  translationStrategy:\n                    description: |-\n                      Configures how the OTLP receiver endpoint translates the incoming metrics.\n\n                      It requires Prometheus >= v3.0.0.\n                    enum:\n                    - NoUTF8EscapingWithSuffixes\n                    - UnderscoreEscapingWithSuffixes\n                    - NoTranslation\n                    type: string\n                type: object\n              overrideHonorLabels:\n                description: |-\n                  When true, Prometheus resolves label conflicts by renaming the labels in the scraped data\n                   to “exported_” for all targets created from ServiceMonitor, PodMonitor and\n                  ScrapeConfig objects. Otherwise the HonorLabels field of the service or pod monitor applies.\n                  In practice,`overrideHonorLaels:true` enforces `honorLabels:false`\n                  for all ServiceMonitor, PodMonitor and ScrapeConfig objects.\n                type: boolean\n              overrideHonorTimestamps:\n                description: |-\n                  When true, Prometheus ignores the timestamps for all the targets created\n                  from service and pod monitors.\n                  Otherwise the HonorTimestamps field of the service or pod monitor applies.\n                type: boolean\n              paused:\n                description: |-\n                  When a Prometheus deployment is paused, no actions except for deletion\n                  will be performed on the underlying objects.\n                type: boolean\n              persistentVolumeClaimRetentionPolicy:\n                description: |-\n                  The field controls if and how PVCs are deleted during the lifecycle of a StatefulSet.\n                  The default behavior is all PVCs are retained.\n                  This is an alpha field from kubernetes 1.23 until 1.26 and a beta field from 1.26.\n                  It requires enabling the StatefulSetAutoDeletePVC feature gate.\n                properties:\n                  whenDeleted:\n                    description: |-\n                      WhenDeleted specifies what happens to PVCs created from StatefulSet\n                      VolumeClaimTemplates when the StatefulSet is deleted. The default policy\n                      of `Retain` causes PVCs to not be affected by StatefulSet deletion. The\n                      `Delete` policy causes those PVCs to be deleted.\n                    type: string\n                  whenScaled:\n                    description: |-\n                      WhenScaled specifies what happens to PVCs created from StatefulSet\n                      VolumeClaimTemplates when the StatefulSet is scaled down. The default\n                      policy of `Retain` causes PVCs to not be affected by a scaledown. The\n                      `Delete` policy causes the associated PVCs for any excess pods above\n                      the replica count to be deleted.\n                    type: string\n                type: object\n              podMetadata:\n                description: |-\n                  PodMetadata configures labels and annotations which are propagated to the Prometheus pods.\n\n                  The following items are reserved and cannot be overridden:\n                  * \"prometheus\" label, set to the name of the Prometheus object.\n                  * \"app.kubernetes.io/instance\" label, set to the name of the Prometheus object.\n                  * \"app.kubernetes.io/managed-by\" label, set to \"prometheus-operator\".\n                  * \"app.kubernetes.io/name\" label, set to \"prometheus\".\n                  * \"app.kubernetes.io/version\" label, set to the Prometheus version.\n                  * \"operator.prometheus.io/name\" label, set to the name of the Prometheus object.\n                  * \"operator.prometheus.io/shard\" label, set to the shard number of the Prometheus object.\n                  * \"kubectl.kubernetes.io/default-container\" annotation, set to \"prometheus\".\n                properties:\n                  annotations:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      Annotations is an unstructured key value map stored with a resource that may be\n                      set by external tools to store and retrieve arbitrary metadata. They are not\n                      queryable and should be preserved when modifying objects.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/\n                    type: object\n                  labels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      Map of string keys and values that can be used to organize and categorize\n                      (scope and select) objects. May match selectors of replication controllers\n                      and services.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/\n                    type: object\n                  name:\n                    description: |-\n                      Name must be unique within a namespace. Is required when creating resources, although\n                      some resources may allow a client to request the generation of an appropriate name\n                      automatically. Name is primarily intended for creation idempotence and configuration\n                      definition.\n                      Cannot be updated.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\n                    type: string\n                type: object\n              podMonitorNamespaceSelector:\n                description: |-\n                  Namespaces to match for PodMonitors discovery. An empty label selector\n                  matches all namespaces. A null label selector (default value) matches the current\n                  namespace only.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              podMonitorSelector:\n                description: |-\n                  PodMonitors to be selected for target discovery. An empty label selector\n                  matches all objects. A null label selector matches no objects.\n\n                  If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector`\n                  and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged.\n                  The Prometheus operator will ensure that the Prometheus configuration's\n                  Secret exists, but it is the responsibility of the user to provide the raw\n                  gzipped Prometheus configuration under the `prometheus.yaml.gz` key.\n                  This behavior is *deprecated* and will be removed in the next major version\n                  of the custom resource definition. It is recommended to use\n                  `spec.additionalScrapeConfigs` instead.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              podTargetLabels:\n                description: |-\n                  PodTargetLabels are appended to the `spec.podTargetLabels` field of all\n                  PodMonitor and ServiceMonitor objects.\n                items:\n                  type: string\n                type: array\n              portName:\n                default: web\n                description: |-\n                  Port name used for the pods and governing service.\n                  Default: \"web\"\n                type: string\n              priorityClassName:\n                description: Priority class assigned to the Pods.\n                type: string\n              probeNamespaceSelector:\n                description: |-\n                  Namespaces to match for Probe discovery. An empty label\n                  selector matches all namespaces. A null label selector matches the\n                  current namespace only.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              probeSelector:\n                description: |-\n                  Probes to be selected for target discovery. An empty label selector\n                  matches all objects. A null label selector matches no objects.\n\n                  If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector`\n                  and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged.\n                  The Prometheus operator will ensure that the Prometheus configuration's\n                  Secret exists, but it is the responsibility of the user to provide the raw\n                  gzipped Prometheus configuration under the `prometheus.yaml.gz` key.\n                  This behavior is *deprecated* and will be removed in the next major version\n                  of the custom resource definition. It is recommended to use\n                  `spec.additionalScrapeConfigs` instead.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              prometheusExternalLabelName:\n                description: |-\n                  Name of Prometheus external label used to denote the Prometheus instance\n                  name. The external label will _not_ be added when the field is set to\n                  the empty string (`\"\"`).\n\n                  Default: \"prometheus\"\n                type: string\n              prometheusRulesExcludedFromEnforce:\n                description: |-\n                  Defines the list of PrometheusRule objects to which the namespace label\n                  enforcement doesn't apply.\n                  This is only relevant when `spec.enforcedNamespaceLabel` is set to true.\n                  Deprecated: use `spec.excludedFromEnforcement` instead.\n                items:\n                  description: |-\n                    PrometheusRuleExcludeConfig enables users to configure excluded\n                    PrometheusRule names and their namespaces to be ignored while enforcing\n                    namespace label for alerts and metrics.\n                  properties:\n                    ruleName:\n                      description: Name of the excluded PrometheusRule object.\n                      type: string\n                    ruleNamespace:\n                      description: Namespace of the excluded PrometheusRule object.\n                      type: string\n                  required:\n                  - ruleName\n                  - ruleNamespace\n                  type: object\n                type: array\n              query:\n                description: QuerySpec defines the configuration of the Promethus query service.\n                properties:\n                  lookbackDelta:\n                    description: The delta difference allowed for retrieving metrics during expression evaluations.\n                    type: string\n                  maxConcurrency:\n                    description: Number of concurrent queries that can be run at once.\n                    format: int32\n                    minimum: 1\n                    type: integer\n                  maxSamples:\n                    description: |-\n                      Maximum number of samples a single query can load into memory. Note that\n                      queries will fail if they would load more samples than this into memory,\n                      so this also limits the number of samples a query can return.\n                    format: int32\n                    type: integer\n                  timeout:\n                    description: Maximum time a query may take before being aborted.\n                    pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                    type: string\n                type: object\n              queryLogFile:\n                description: |-\n                  queryLogFile specifies where the file to which PromQL queries are logged.\n\n                  If the filename has an empty path, e.g. 'query.log', The Prometheus Pods\n                  will mount the file into an emptyDir volume at `/var/log/prometheus`.\n                  If a full path is provided, e.g. '/var/log/prometheus/query.log', you\n                  must mount a volume in the specified directory and it must be writable.\n                  This is because the prometheus container runs with a read-only root\n                  filesystem for security reasons.\n                  Alternatively, the location can be set to a standard I/O stream, e.g.\n                  `/dev/stdout`, to log query information to the default Prometheus log\n                  stream.\n                type: string\n              reloadStrategy:\n                description: |-\n                  Defines the strategy used to reload the Prometheus configuration.\n                  If not specified, the configuration is reloaded using the /-/reload HTTP endpoint.\n                enum:\n                - HTTP\n                - ProcessSignal\n                type: string\n              remoteRead:\n                description: Defines the list of remote read configurations.\n                items:\n                  description: |-\n                    RemoteReadSpec defines the configuration for Prometheus to read back samples\n                    from a remote endpoint.\n                  properties:\n                    authorization:\n                      description: |-\n                        Authorization section for the URL.\n\n                        It requires Prometheus >= v2.26.0.\n\n                        Cannot be set at the same time as `basicAuth`, or `oauth2`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        credentialsFile:\n                          description: File to read a secret from, mutually exclusive with `credentials`.\n                          type: string\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: |-\n                        BasicAuth configuration for the URL.\n\n                        Cannot be set at the same time as `authorization`, or `oauth2`.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    bearerToken:\n                      description: |-\n                        *Warning: this field shouldn't be used because the token value appears\n                        in clear-text. Prefer using `authorization`.*\n\n                        Deprecated: this will be removed in a future release.\n                      type: string\n                    bearerTokenFile:\n                      description: |-\n                        File from which to read the bearer token for the URL.\n\n                        Deprecated: this will be removed in a future release. Prefer using `authorization`.\n                      type: string\n                    filterExternalLabels:\n                      description: |-\n                        Whether to use the external labels as selectors for the remote read endpoint.\n\n                        It requires Prometheus >= v2.34.0.\n                      type: boolean\n                    followRedirects:\n                      description: |-\n                        Configure whether HTTP requests follow HTTP 3xx redirects.\n\n                        It requires Prometheus >= v2.26.0.\n                      type: boolean\n                    headers:\n                      additionalProperties:\n                        type: string\n                      description: |-\n                        Custom HTTP headers to be sent along with each remote read request.\n                        Be aware that headers that are set by Prometheus itself can't be overwritten.\n                        Only valid in Prometheus versions 2.26.0 and newer.\n                      type: object\n                    name:\n                      description: |-\n                        The name of the remote read queue, it must be unique if specified. The\n                        name is used in metrics and logging in order to differentiate read\n                        configurations.\n\n                        It requires Prometheus >= v2.15.0.\n                      type: string\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        OAuth2 configuration for the URL.\n\n                        It requires Prometheus >= v2.27.0.\n\n                        Cannot be set at the same time as `authorization`, or `basicAuth`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    readRecent:\n                      description: |-\n                        Whether reads should be made for queries for time ranges that\n                        the local storage should have complete data for.\n                      type: boolean\n                    remoteTimeout:\n                      description: Timeout for requests to the remote read endpoint.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    requiredMatchers:\n                      additionalProperties:\n                        type: string\n                      description: |-\n                        An optional list of equality matchers which have to be present\n                        in a selector to query the remote read endpoint.\n                      type: object\n                    tlsConfig:\n                      description: TLS Config to use for the URL.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        caFile:\n                          description: Path to the CA cert in the Prometheus container to use for the targets.\n                          type: string\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        certFile:\n                          description: Path to the client cert file in the Prometheus container for the targets.\n                          type: string\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keyFile:\n                          description: Path to the client key file in the Prometheus container for the targets.\n                          type: string\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                    url:\n                      description: The URL of the endpoint to query from.\n                      type: string\n                  required:\n                  - url\n                  type: object\n                type: array\n              remoteWrite:\n                description: Defines the list of remote write configurations.\n                items:\n                  description: |-\n                    RemoteWriteSpec defines the configuration to write samples from Prometheus\n                    to a remote endpoint.\n                  properties:\n                    authorization:\n                      description: |-\n                        Authorization section for the URL.\n\n                        It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0.\n\n                        Cannot be set at the same time as `sigv4`, `basicAuth`, `oauth2`, or `azureAd`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        credentialsFile:\n                          description: File to read a secret from, mutually exclusive with `credentials`.\n                          type: string\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    azureAd:\n                      description: |-\n                        AzureAD for the URL.\n\n                        It requires Prometheus >= v2.45.0 or Thanos >= v0.31.0.\n\n                        Cannot be set at the same time as `authorization`, `basicAuth`, `oauth2`, or `sigv4`.\n                      properties:\n                        cloud:\n                          description: The Azure Cloud. Options are 'AzurePublic', 'AzureChina', or 'AzureGovernment'.\n                          enum:\n                          - AzureChina\n                          - AzureGovernment\n                          - AzurePublic\n                          type: string\n                        managedIdentity:\n                          description: |-\n                            ManagedIdentity defines the Azure User-assigned Managed identity.\n                            Cannot be set at the same time as `oauth` or `sdk`.\n                          properties:\n                            clientId:\n                              description: The client id\n                              type: string\n                          required:\n                          - clientId\n                          type: object\n                        oauth:\n                          description: |-\n                            OAuth defines the oauth config that is being used to authenticate.\n                            Cannot be set at the same time as `managedIdentity` or `sdk`.\n\n                            It requires Prometheus >= v2.48.0 or Thanos >= v0.31.0.\n                          properties:\n                            clientId:\n                              description: '`clientID` is the clientId of the Azure Active Directory application that is being used to authenticate.'\n                              minLength: 1\n                              type: string\n                            clientSecret:\n                              description: '`clientSecret` specifies a key of a Secret containing the client secret of the Azure Active Directory application that is being used to authenticate.'\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            tenantId:\n                              description: '`tenantId` is the tenant ID of the Azure Active Directory application that is being used to authenticate.'\n                              minLength: 1\n                              pattern: ^[0-9a-zA-Z-.]+$\n                              type: string\n                          required:\n                          - clientId\n                          - clientSecret\n                          - tenantId\n                          type: object\n                        sdk:\n                          description: |-\n                            SDK defines the Azure SDK config that is being used to authenticate.\n                            See https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication\n                            Cannot be set at the same time as `oauth` or `managedIdentity`.\n\n                            It requires Prometheus >= v2.52.0 or Thanos >= v0.36.0.\n                          properties:\n                            tenantId:\n                              description: '`tenantId` is the tenant ID of the azure active directory application that is being used to authenticate.'\n                              pattern: ^[0-9a-zA-Z-.]+$\n                              type: string\n                          type: object\n                      type: object\n                    basicAuth:\n                      description: |-\n                        BasicAuth configuration for the URL.\n\n                        Cannot be set at the same time as `sigv4`, `authorization`, `oauth2`, or `azureAd`.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    bearerToken:\n                      description: |-\n                        *Warning: this field shouldn't be used because the token value appears\n                        in clear-text. Prefer using `authorization`.*\n\n                        Deprecated: this will be removed in a future release.\n                      type: string\n                    bearerTokenFile:\n                      description: |-\n                        File from which to read bearer token for the URL.\n\n                        Deprecated: this will be removed in a future release. Prefer using `authorization`.\n                      type: string\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: |-\n                        Configure whether HTTP requests follow HTTP 3xx redirects.\n\n                        It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0.\n                      type: boolean\n                    headers:\n                      additionalProperties:\n                        type: string\n                      description: |-\n                        Custom HTTP headers to be sent along with each remote write request.\n                        Be aware that headers that are set by Prometheus itself can't be overwritten.\n\n                        It requires Prometheus >= v2.25.0 or Thanos >= v0.24.0.\n                      type: object\n                    messageVersion:\n                      description: |-\n                        The Remote Write message's version to use when writing to the endpoint.\n\n                        `Version1.0` corresponds to the `prometheus.WriteRequest` protobuf message introduced in Remote Write 1.0.\n                        `Version2.0` corresponds to the `io.prometheus.write.v2.Request` protobuf message introduced in Remote Write 2.0.\n\n                        When `Version2.0` is selected, Prometheus will automatically be\n                        configured to append the metadata of scraped metrics to the WAL.\n\n                        Before setting this field, consult with your remote storage provider\n                        what message version it supports.\n\n                        It requires Prometheus >= v2.54.0 or Thanos >= v0.37.0.\n                      enum:\n                      - V1.0\n                      - V2.0\n                      type: string\n                    metadataConfig:\n                      description: MetadataConfig configures the sending of series metadata to the remote storage.\n                      properties:\n                        maxSamplesPerSend:\n                          description: |-\n                            MaxSamplesPerSend is the maximum number of metadata samples per send.\n\n                            It requires Prometheus >= v2.29.0.\n                          format: int32\n                          minimum: -1\n                          type: integer\n                        send:\n                          description: Defines whether metric metadata is sent to the remote storage or not.\n                          type: boolean\n                        sendInterval:\n                          description: Defines how frequently metric metadata is sent to the remote storage.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                      type: object\n                    name:\n                      description: |-\n                        The name of the remote write queue, it must be unique if specified. The\n                        name is used in metrics and logging in order to differentiate queues.\n\n                        It requires Prometheus >= v2.15.0 or Thanos >= 0.24.0.\n                      type: string\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        OAuth2 configuration for the URL.\n\n                        It requires Prometheus >= v2.27.0 or Thanos >= v0.24.0.\n\n                        Cannot be set at the same time as `sigv4`, `authorization`, `basicAuth`, or `azureAd`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    queueConfig:\n                      description: QueueConfig allows tuning of the remote write queue parameters.\n                      properties:\n                        batchSendDeadline:\n                          description: BatchSendDeadline is the maximum time a sample will wait in buffer.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                        capacity:\n                          description: |-\n                            Capacity is the number of samples to buffer per shard before we start\n                            dropping them.\n                          type: integer\n                        maxBackoff:\n                          description: MaxBackoff is the maximum retry delay.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                        maxRetries:\n                          description: MaxRetries is the maximum number of times to retry a batch on recoverable errors.\n                          type: integer\n                        maxSamplesPerSend:\n                          description: MaxSamplesPerSend is the maximum number of samples per send.\n                          type: integer\n                        maxShards:\n                          description: MaxShards is the maximum number of shards, i.e. amount of concurrency.\n                          type: integer\n                        minBackoff:\n                          description: MinBackoff is the initial retry delay. Gets doubled for every retry.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                        minShards:\n                          description: MinShards is the minimum number of shards, i.e. amount of concurrency.\n                          type: integer\n                        retryOnRateLimit:\n                          description: |-\n                            Retry upon receiving a 429 status code from the remote-write storage.\n\n                            This is an *experimental feature*, it may change in any upcoming release\n                            in a breaking way.\n                          type: boolean\n                        sampleAgeLimit:\n                          description: |-\n                            SampleAgeLimit drops samples older than the limit.\n                            It requires Prometheus >= v2.50.0 or Thanos >= v0.32.0.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                      type: object\n                    remoteTimeout:\n                      description: Timeout for requests to the remote write endpoint.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    roundRobinDNS:\n                      description: |-\n                        When enabled:\n                            - The remote-write mechanism will resolve the hostname via DNS.\n                            - It will randomly select one of the resolved IP addresses and connect to it.\n\n                        When disabled (default behavior):\n                            - The Go standard library will handle hostname resolution.\n                            - It will attempt connections to each resolved IP address sequentially.\n\n                        Note: The connection timeout applies to the entire resolution and connection process.\n                              If disabled, the timeout is distributed across all connection attempts.\n\n                        It requires Prometheus >= v3.1.0 or Thanos >= v0.38.0.\n                      type: boolean\n                    sendExemplars:\n                      description: |-\n                        Enables sending of exemplars over remote write. Note that\n                        exemplar-storage itself must be enabled using the `spec.enableFeatures`\n                        option for exemplars to be scraped in the first place.\n\n                        It requires Prometheus >= v2.27.0 or Thanos >= v0.24.0.\n                      type: boolean\n                    sendNativeHistograms:\n                      description: |-\n                        Enables sending of native histograms, also known as sparse histograms\n                        over remote write.\n\n                        It requires Prometheus >= v2.40.0 or Thanos >= v0.30.0.\n                      type: boolean\n                    sigv4:\n                      description: |-\n                        Sigv4 allows to configures AWS's Signature Verification 4 for the URL.\n\n                        It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0.\n\n                        Cannot be set at the same time as `authorization`, `basicAuth`, `oauth2`, or `azureAd`.\n                      properties:\n                        accessKey:\n                          description: |-\n                            AccessKey is the AWS API key. If not specified, the environment variable\n                            `AWS_ACCESS_KEY_ID` is used.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        profile:\n                          description: Profile is the named AWS profile used to authenticate.\n                          type: string\n                        region:\n                          description: Region is the AWS region. If blank, the region from the default credentials chain used.\n                          type: string\n                        roleArn:\n                          description: RoleArn is the named AWS profile used to authenticate.\n                          type: string\n                        secretKey:\n                          description: |-\n                            SecretKey is the AWS API secret. If not specified, the environment\n                            variable `AWS_SECRET_ACCESS_KEY` is used.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    tlsConfig:\n                      description: TLS Config to use for the URL.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        caFile:\n                          description: Path to the CA cert in the Prometheus container to use for the targets.\n                          type: string\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        certFile:\n                          description: Path to the client cert file in the Prometheus container for the targets.\n                          type: string\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keyFile:\n                          description: Path to the client key file in the Prometheus container for the targets.\n                          type: string\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                    url:\n                      description: The URL of the endpoint to send samples to.\n                      minLength: 1\n                      type: string\n                    writeRelabelConfigs:\n                      description: The list of remote write relabel configurations.\n                      items:\n                        description: |-\n                          RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                          scraped samples and remote write samples.\n\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        properties:\n                          action:\n                            default: replace\n                            description: |-\n                              Action to perform based on the regex matching.\n\n                              `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                              `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                              Default: \"Replace\"\n                            enum:\n                            - replace\n                            - Replace\n                            - keep\n                            - Keep\n                            - drop\n                            - Drop\n                            - hashmod\n                            - HashMod\n                            - labelmap\n                            - LabelMap\n                            - labeldrop\n                            - LabelDrop\n                            - labelkeep\n                            - LabelKeep\n                            - lowercase\n                            - Lowercase\n                            - uppercase\n                            - Uppercase\n                            - keepequal\n                            - KeepEqual\n                            - dropequal\n                            - DropEqual\n                            type: string\n                          modulus:\n                            description: |-\n                              Modulus to take of the hash of the source label values.\n\n                              Only applicable when the action is `HashMod`.\n                            format: int64\n                            type: integer\n                          regex:\n                            description: Regular expression against which the extracted value is matched.\n                            type: string\n                          replacement:\n                            description: |-\n                              Replacement value against which a Replace action is performed if the\n                              regular expression matches.\n\n                              Regex capture groups are available.\n                            type: string\n                          separator:\n                            description: Separator is the string between concatenated SourceLabels.\n                            type: string\n                          sourceLabels:\n                            description: |-\n                              The source labels select values from existing labels. Their content is\n                              concatenated using the configured Separator and matched against the\n                              configured regular expression.\n                            items:\n                              description: |-\n                                LabelName is a valid Prometheus label name which may only contain ASCII\n                                letters, numbers, as well as underscores.\n                              pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                              type: string\n                            type: array\n                          targetLabel:\n                            description: |-\n                              Label to which the resulting string is written in a replacement.\n\n                              It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                              `KeepEqual` and `DropEqual` actions.\n\n                              Regex capture groups are available.\n                            type: string\n                        type: object\n                      type: array\n                  required:\n                  - url\n                  type: object\n                type: array\n              remoteWriteReceiverMessageVersions:\n                description: |-\n                  List of the protobuf message versions to accept when receiving the\n                  remote writes.\n\n                  It requires Prometheus >= v2.54.0.\n                items:\n                  enum:\n                  - V1.0\n                  - V2.0\n                  type: string\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: set\n              replicaExternalLabelName:\n                description: |-\n                  Name of Prometheus external label used to denote the replica name.\n                  The external label will _not_ be added when the field is set to the\n                  empty string (`\"\"`).\n\n                  Default: \"prometheus_replica\"\n                type: string\n              replicas:\n                description: |-\n                  Number of replicas of each shard to deploy for a Prometheus deployment.\n                  `spec.replicas` multiplied by `spec.shards` is the total number of Pods\n                  created.\n\n                  Default: 1\n                format: int32\n                type: integer\n              resources:\n                description: Defines the resources requests and limits of the 'prometheus' container.\n                properties:\n                  claims:\n                    description: |-\n                      Claims lists the names of resources, defined in spec.resourceClaims,\n                      that are used by this container.\n\n                      This is an alpha field and requires enabling the\n                      DynamicResourceAllocation feature gate.\n\n                      This field is immutable. It can only be set for containers.\n                    items:\n                      description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                      properties:\n                        name:\n                          description: |-\n                            Name must match the name of one entry in pod.spec.resourceClaims of\n                            the Pod where this field is used. It makes that resource available\n                            inside a container.\n                          type: string\n                        request:\n                          description: |-\n                            Request is the name chosen for a request in the referenced claim.\n                            If empty, everything from the claim is made available, otherwise\n                            only the result of this request.\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    type: array\n                    x-kubernetes-list-map-keys:\n                    - name\n                    x-kubernetes-list-type: map\n                  limits:\n                    additionalProperties:\n                      anyOf:\n                      - type: integer\n                      - type: string\n                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                      x-kubernetes-int-or-string: true\n                    description: |-\n                      Limits describes the maximum amount of compute resources allowed.\n                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                    type: object\n                  requests:\n                    additionalProperties:\n                      anyOf:\n                      - type: integer\n                      - type: string\n                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                      x-kubernetes-int-or-string: true\n                    description: |-\n                      Requests describes the minimum amount of compute resources required.\n                      If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                      otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                    type: object\n                type: object\n              retention:\n                description: |-\n                  How long to retain the Prometheus data.\n\n                  Default: \"24h\" if `spec.retention` and `spec.retentionSize` are empty.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              retentionSize:\n                description: Maximum number of bytes used by the Prometheus data.\n                pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$\n                type: string\n              routePrefix:\n                description: |-\n                  The route prefix Prometheus registers HTTP handlers for.\n\n                  This is useful when using `spec.externalURL`, and a proxy is rewriting\n                  HTTP routes of a request, and the actual ExternalURL is still true, but\n                  the server serves requests under a different route prefix. For example\n                  for use with `kubectl proxy`.\n                type: string\n              ruleNamespaceSelector:\n                description: |-\n                  Namespaces to match for PrometheusRule discovery. An empty label selector\n                  matches all namespaces. A null label selector matches the current\n                  namespace only.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              ruleQueryOffset:\n                description: |-\n                  Defines the offset the rule evaluation timestamp of this particular group by the specified duration into the past.\n                  It requires Prometheus >= v2.53.0.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              ruleSelector:\n                description: |-\n                  PrometheusRule objects to be selected for rule evaluation. An empty\n                  label selector matches all objects. A null label selector matches no\n                  objects.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              rules:\n                description: Defines the configuration of the Prometheus rules' engine.\n                properties:\n                  alert:\n                    description: |-\n                      Defines the parameters of the Prometheus rules' engine.\n\n                      Any update to these parameters trigger a restart of the pods.\n                    properties:\n                      forGracePeriod:\n                        description: |-\n                          Minimum duration between alert and restored 'for' state.\n\n                          This is maintained only for alerts with a configured 'for' time greater\n                          than the grace period.\n                        type: string\n                      forOutageTolerance:\n                        description: |-\n                          Max time to tolerate prometheus outage for restoring 'for' state of\n                          alert.\n                        type: string\n                      resendDelay:\n                        description: |-\n                          Minimum amount of time to wait before resending an alert to\n                          Alertmanager.\n                        type: string\n                    type: object\n                type: object\n              runtime:\n                description: RuntimeConfig configures the values for the Prometheus process behavior\n                properties:\n                  goGC:\n                    description: |-\n                      The Go garbage collection target percentage. Lowering this number may increase the CPU usage.\n                      See: https://tip.golang.org/doc/gc-guide#GOGC\n                    format: int32\n                    minimum: -1\n                    type: integer\n                type: object\n              sampleLimit:\n                description: |-\n                  SampleLimit defines per-scrape limit on number of scraped samples that will be accepted.\n                  Only valid in Prometheus versions 2.45.0 and newer.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedSampleLimit.\n                format: int64\n                type: integer\n              scrapeClasses:\n                description: |-\n                  List of scrape classes to expose to scraping objects such as\n                  PodMonitors, ServiceMonitors, Probes and ScrapeConfigs.\n\n                  This is an *experimental feature*, it may change in any upcoming release\n                  in a breaking way.\n                items:\n                  properties:\n                    attachMetadata:\n                      description: |-\n                        AttachMetadata configures additional metadata to the discovered targets.\n                        When the scrape object defines its own configuration, it takes\n                        precedence over the scrape class configuration.\n                      properties:\n                        node:\n                          description: |-\n                            When set to true, Prometheus attaches node metadata to the discovered\n                            targets.\n\n                            The Prometheus service account must have the `list` and `watch`\n                            permissions on the `Nodes` objects.\n                          type: boolean\n                      type: object\n                    authorization:\n                      description: |-\n                        Authorization section for the ScrapeClass.\n                        It will only apply if the scrape resource doesn't specify any Authorization.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        credentialsFile:\n                          description: File to read a secret from, mutually exclusive with `credentials`.\n                          type: string\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    default:\n                      description: |-\n                        Default indicates that the scrape applies to all scrape objects that\n                        don't configure an explicit scrape class name.\n\n                        Only one scrape class can be set as the default.\n                      type: boolean\n                    fallbackScrapeProtocol:\n                      description: |-\n                        The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type.\n                        It will only apply if the scrape resource doesn't specify any FallbackScrapeProtocol\n\n                        It requires Prometheus >= v3.0.0.\n                      enum:\n                      - PrometheusProto\n                      - OpenMetricsText0.0.1\n                      - OpenMetricsText1.0.0\n                      - PrometheusText0.0.4\n                      - PrometheusText1.0.0\n                      type: string\n                    metricRelabelings:\n                      description: |-\n                        MetricRelabelings configures the relabeling rules to apply to all samples before ingestion.\n\n                        The Operator adds the scrape class metric relabelings defined here.\n                        Then the Operator adds the target-specific metric relabelings defined in ServiceMonitors, PodMonitors, Probes and ScrapeConfigs.\n                        Then the Operator adds namespace enforcement relabeling rule, specified in '.spec.enforcedNamespaceLabel'.\n\n                        More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs\n                      items:\n                        description: |-\n                          RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                          scraped samples and remote write samples.\n\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        properties:\n                          action:\n                            default: replace\n                            description: |-\n                              Action to perform based on the regex matching.\n\n                              `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                              `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                              Default: \"Replace\"\n                            enum:\n                            - replace\n                            - Replace\n                            - keep\n                            - Keep\n                            - drop\n                            - Drop\n                            - hashmod\n                            - HashMod\n                            - labelmap\n                            - LabelMap\n                            - labeldrop\n                            - LabelDrop\n                            - labelkeep\n                            - LabelKeep\n                            - lowercase\n                            - Lowercase\n                            - uppercase\n                            - Uppercase\n                            - keepequal\n                            - KeepEqual\n                            - dropequal\n                            - DropEqual\n                            type: string\n                          modulus:\n                            description: |-\n                              Modulus to take of the hash of the source label values.\n\n                              Only applicable when the action is `HashMod`.\n                            format: int64\n                            type: integer\n                          regex:\n                            description: Regular expression against which the extracted value is matched.\n                            type: string\n                          replacement:\n                            description: |-\n                              Replacement value against which a Replace action is performed if the\n                              regular expression matches.\n\n                              Regex capture groups are available.\n                            type: string\n                          separator:\n                            description: Separator is the string between concatenated SourceLabels.\n                            type: string\n                          sourceLabels:\n                            description: |-\n                              The source labels select values from existing labels. Their content is\n                              concatenated using the configured Separator and matched against the\n                              configured regular expression.\n                            items:\n                              description: |-\n                                LabelName is a valid Prometheus label name which may only contain ASCII\n                                letters, numbers, as well as underscores.\n                              pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                              type: string\n                            type: array\n                          targetLabel:\n                            description: |-\n                              Label to which the resulting string is written in a replacement.\n\n                              It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                              `KeepEqual` and `DropEqual` actions.\n\n                              Regex capture groups are available.\n                            type: string\n                        type: object\n                      type: array\n                    name:\n                      description: Name of the scrape class.\n                      minLength: 1\n                      type: string\n                    relabelings:\n                      description: |-\n                        Relabelings configures the relabeling rules to apply to all scrape targets.\n\n                        The Operator automatically adds relabelings for a few standard Kubernetes fields\n                        like `__meta_kubernetes_namespace` and `__meta_kubernetes_service_name`.\n                        Then the Operator adds the scrape class relabelings defined here.\n                        Then the Operator adds the target-specific relabelings defined in the scrape object.\n\n                        More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                      items:\n                        description: |-\n                          RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                          scraped samples and remote write samples.\n\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        properties:\n                          action:\n                            default: replace\n                            description: |-\n                              Action to perform based on the regex matching.\n\n                              `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                              `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                              Default: \"Replace\"\n                            enum:\n                            - replace\n                            - Replace\n                            - keep\n                            - Keep\n                            - drop\n                            - Drop\n                            - hashmod\n                            - HashMod\n                            - labelmap\n                            - LabelMap\n                            - labeldrop\n                            - LabelDrop\n                            - labelkeep\n                            - LabelKeep\n                            - lowercase\n                            - Lowercase\n                            - uppercase\n                            - Uppercase\n                            - keepequal\n                            - KeepEqual\n                            - dropequal\n                            - DropEqual\n                            type: string\n                          modulus:\n                            description: |-\n                              Modulus to take of the hash of the source label values.\n\n                              Only applicable when the action is `HashMod`.\n                            format: int64\n                            type: integer\n                          regex:\n                            description: Regular expression against which the extracted value is matched.\n                            type: string\n                          replacement:\n                            description: |-\n                              Replacement value against which a Replace action is performed if the\n                              regular expression matches.\n\n                              Regex capture groups are available.\n                            type: string\n                          separator:\n                            description: Separator is the string between concatenated SourceLabels.\n                            type: string\n                          sourceLabels:\n                            description: |-\n                              The source labels select values from existing labels. Their content is\n                              concatenated using the configured Separator and matched against the\n                              configured regular expression.\n                            items:\n                              description: |-\n                                LabelName is a valid Prometheus label name which may only contain ASCII\n                                letters, numbers, as well as underscores.\n                              pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                              type: string\n                            type: array\n                          targetLabel:\n                            description: |-\n                              Label to which the resulting string is written in a replacement.\n\n                              It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                              `KeepEqual` and `DropEqual` actions.\n\n                              Regex capture groups are available.\n                            type: string\n                        type: object\n                      type: array\n                    tlsConfig:\n                      description: |-\n                        TLSConfig defines the TLS settings to use for the scrape. When the\n                        scrape objects define their own CA, certificate and/or key, they take\n                        precedence over the corresponding scrape class fields.\n\n                        For now only the `caFile`, `certFile` and `keyFile` fields are supported.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        caFile:\n                          description: Path to the CA cert in the Prometheus container to use for the targets.\n                          type: string\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        certFile:\n                          description: Path to the client cert file in the Prometheus container for the targets.\n                          type: string\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keyFile:\n                          description: Path to the client key file in the Prometheus container for the targets.\n                          type: string\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  required:\n                  - name\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n              scrapeClassicHistograms:\n                description: |-\n                  Whether to scrape a classic histogram that is also exposed as a native histogram.\n\n                  Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration.\n\n                  It requires Prometheus >= v3.5.0.\n                type: boolean\n              scrapeConfigNamespaceSelector:\n                description: |-\n                  Namespaces to match for ScrapeConfig discovery. An empty label selector\n                  matches all namespaces. A null label selector matches the current\n                  namespace only.\n\n                  Note that the ScrapeConfig custom resource definition is currently at Alpha level.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              scrapeConfigSelector:\n                description: |-\n                  ScrapeConfigs to be selected for target discovery. An empty label\n                  selector matches all objects. A null label selector matches no objects.\n\n                  If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector`\n                  and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged.\n                  The Prometheus operator will ensure that the Prometheus configuration's\n                  Secret exists, but it is the responsibility of the user to provide the raw\n                  gzipped Prometheus configuration under the `prometheus.yaml.gz` key.\n                  This behavior is *deprecated* and will be removed in the next major version\n                  of the custom resource definition. It is recommended to use\n                  `spec.additionalScrapeConfigs` instead.\n\n                  Note that the ScrapeConfig custom resource definition is currently at Alpha level.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              scrapeFailureLogFile:\n                description: |-\n                  File to which scrape failures are logged.\n                  Reloading the configuration will reopen the file.\n\n                  If the filename has an empty path, e.g. 'file.log', The Prometheus Pods\n                  will mount the file into an emptyDir volume at `/var/log/prometheus`.\n                  If a full path is provided, e.g. '/var/log/prometheus/file.log', you\n                  must mount a volume in the specified directory and it must be writable.\n                  It requires Prometheus >= v2.55.0.\n                minLength: 1\n                type: string\n              scrapeInterval:\n                default: 30s\n                description: |-\n                  Interval between consecutive scrapes.\n\n                  Default: \"30s\"\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              scrapeProtocols:\n                description: |-\n                  The protocols to negotiate during a scrape. It tells clients the\n                  protocols supported by Prometheus in order of preference (from most to least preferred).\n\n                  If unset, Prometheus uses its default value.\n\n                  It requires Prometheus >= v2.49.0.\n\n                  `PrometheusText1.0.0` requires Prometheus >= v3.0.0.\n                items:\n                  description: |-\n                    ScrapeProtocol represents a protocol used by Prometheus for scraping metrics.\n                    Supported values are:\n                    * `OpenMetricsText0.0.1`\n                    * `OpenMetricsText1.0.0`\n                    * `PrometheusProto`\n                    * `PrometheusText0.0.4`\n                    * `PrometheusText1.0.0`\n                  enum:\n                  - PrometheusProto\n                  - OpenMetricsText0.0.1\n                  - OpenMetricsText1.0.0\n                  - PrometheusText0.0.4\n                  - PrometheusText1.0.0\n                  type: string\n                type: array\n                x-kubernetes-list-type: set\n              scrapeTimeout:\n                description: |-\n                  Number of seconds to wait until a scrape request times out.\n                  The value cannot be greater than the scrape interval otherwise the operator will reject the resource.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              secrets:\n                description: |-\n                  Secrets is a list of Secrets in the same namespace as the Prometheus\n                  object, which shall be mounted into the Prometheus Pods.\n                  Each Secret is added to the StatefulSet definition as a volume named `secret-<secret-name>`.\n                  The Secrets are mounted into /etc/prometheus/secrets/<secret-name> in the 'prometheus' container.\n                items:\n                  type: string\n                type: array\n                x-kubernetes-list-type: set\n              securityContext:\n                description: |-\n                  SecurityContext holds pod-level security attributes and common container settings.\n                  This defaults to the default PodSecurityContext.\n                properties:\n                  appArmorProfile:\n                    description: |-\n                      appArmorProfile is the AppArmor options to use by the containers in this pod.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    properties:\n                      localhostProfile:\n                        description: |-\n                          localhostProfile indicates a profile loaded on the node that should be used.\n                          The profile must be preconfigured on the node to work.\n                          Must match the loaded name of the profile.\n                          Must be set if and only if type is \"Localhost\".\n                        type: string\n                      type:\n                        description: |-\n                          type indicates which kind of AppArmor profile will be applied.\n                          Valid options are:\n                            Localhost - a profile pre-loaded on the node.\n                            RuntimeDefault - the container runtime's default profile.\n                            Unconfined - no AppArmor enforcement.\n                        type: string\n                    required:\n                    - type\n                    type: object\n                  fsGroup:\n                    description: |-\n                      A special supplemental group that applies to all containers in a pod.\n                      Some volume types allow the Kubelet to change the ownership of that volume\n                      to be owned by the pod:\n\n                      1. The owning GID will be the FSGroup\n                      2. The setgid bit is set (new files created in the volume will be owned by FSGroup)\n                      3. The permission bits are OR'd with rw-rw----\n\n                      If unset, the Kubelet will not modify the ownership and permissions of any volume.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    format: int64\n                    type: integer\n                  fsGroupChangePolicy:\n                    description: |-\n                      fsGroupChangePolicy defines behavior of changing ownership and permission of the volume\n                      before being exposed inside Pod. This field will only apply to\n                      volume types which support fsGroup based ownership(and permissions).\n                      It will have no effect on ephemeral volume types such as: secret, configmaps\n                      and emptydir.\n                      Valid values are \"OnRootMismatch\" and \"Always\". If not specified, \"Always\" is used.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    type: string\n                  runAsGroup:\n                    description: |-\n                      The GID to run the entrypoint of the container process.\n                      Uses runtime default if unset.\n                      May also be set in SecurityContext.  If set in both SecurityContext and\n                      PodSecurityContext, the value specified in SecurityContext takes precedence\n                      for that container.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    format: int64\n                    type: integer\n                  runAsNonRoot:\n                    description: |-\n                      Indicates that the container must run as a non-root user.\n                      If true, the Kubelet will validate the image at runtime to ensure that it\n                      does not run as UID 0 (root) and fail to start the container if it does.\n                      If unset or false, no such validation will be performed.\n                      May also be set in SecurityContext.  If set in both SecurityContext and\n                      PodSecurityContext, the value specified in SecurityContext takes precedence.\n                    type: boolean\n                  runAsUser:\n                    description: |-\n                      The UID to run the entrypoint of the container process.\n                      Defaults to user specified in image metadata if unspecified.\n                      May also be set in SecurityContext.  If set in both SecurityContext and\n                      PodSecurityContext, the value specified in SecurityContext takes precedence\n                      for that container.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    format: int64\n                    type: integer\n                  seLinuxChangePolicy:\n                    description: |-\n                      seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod.\n                      It has no effect on nodes that do not support SELinux or to volumes does not support SELinux.\n                      Valid values are \"MountOption\" and \"Recursive\".\n\n                      \"Recursive\" means relabeling of all files on all Pod volumes by the container runtime.\n                      This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.\n\n                      \"MountOption\" mounts all eligible Pod volumes with `-o context` mount option.\n                      This requires all Pods that share the same volume to use the same SELinux label.\n                      It is not possible to share the same volume among privileged and unprivileged Pods.\n                      Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes\n                      whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their\n                      CSIDriver instance. Other volumes are always re-labelled recursively.\n                      \"MountOption\" value is allowed only when SELinuxMount feature gate is enabled.\n\n                      If not specified and SELinuxMount feature gate is enabled, \"MountOption\" is used.\n                      If not specified and SELinuxMount feature gate is disabled, \"MountOption\" is used for ReadWriteOncePod volumes\n                      and \"Recursive\" for all other volumes.\n\n                      This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.\n\n                      All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    type: string\n                  seLinuxOptions:\n                    description: |-\n                      The SELinux context to be applied to all containers.\n                      If unspecified, the container runtime will allocate a random SELinux context for each\n                      container.  May also be set in SecurityContext.  If set in\n                      both SecurityContext and PodSecurityContext, the value specified in SecurityContext\n                      takes precedence for that container.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    properties:\n                      level:\n                        description: Level is SELinux level label that applies to the container.\n                        type: string\n                      role:\n                        description: Role is a SELinux role label that applies to the container.\n                        type: string\n                      type:\n                        description: Type is a SELinux type label that applies to the container.\n                        type: string\n                      user:\n                        description: User is a SELinux user label that applies to the container.\n                        type: string\n                    type: object\n                  seccompProfile:\n                    description: |-\n                      The seccomp options to use by the containers in this pod.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    properties:\n                      localhostProfile:\n                        description: |-\n                          localhostProfile indicates a profile defined in a file on the node should be used.\n                          The profile must be preconfigured on the node to work.\n                          Must be a descending path, relative to the kubelet's configured seccomp profile location.\n                          Must be set if type is \"Localhost\". Must NOT be set for any other type.\n                        type: string\n                      type:\n                        description: |-\n                          type indicates which kind of seccomp profile will be applied.\n                          Valid options are:\n\n                          Localhost - a profile defined in a file on the node should be used.\n                          RuntimeDefault - the container runtime default profile should be used.\n                          Unconfined - no profile should be applied.\n                        type: string\n                    required:\n                    - type\n                    type: object\n                  supplementalGroups:\n                    description: |-\n                      A list of groups applied to the first process run in each container, in\n                      addition to the container's primary GID and fsGroup (if specified).  If\n                      the SupplementalGroupsPolicy feature is enabled, the\n                      supplementalGroupsPolicy field determines whether these are in addition\n                      to or instead of any group memberships defined in the container image.\n                      If unspecified, no additional groups are added, though group memberships\n                      defined in the container image may still be used, depending on the\n                      supplementalGroupsPolicy field.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    items:\n                      format: int64\n                      type: integer\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  supplementalGroupsPolicy:\n                    description: |-\n                      Defines how supplemental groups of the first container processes are calculated.\n                      Valid values are \"Merge\" and \"Strict\". If not specified, \"Merge\" is used.\n                      (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled\n                      and the container runtime must implement support for this feature.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    type: string\n                  sysctls:\n                    description: |-\n                      Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported\n                      sysctls (by the container runtime) might fail to launch.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    items:\n                      description: Sysctl defines a kernel parameter to be set\n                      properties:\n                        name:\n                          description: Name of a property to set\n                          type: string\n                        value:\n                          description: Value of a property to set\n                          type: string\n                      required:\n                      - name\n                      - value\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  windowsOptions:\n                    description: |-\n                      The Windows specific settings applied to all containers.\n                      If unspecified, the options within a container's SecurityContext will be used.\n                      If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.\n                      Note that this field cannot be set when spec.os.name is linux.\n                    properties:\n                      gmsaCredentialSpec:\n                        description: |-\n                          GMSACredentialSpec is where the GMSA admission webhook\n                          (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the\n                          GMSA credential spec named by the GMSACredentialSpecName field.\n                        type: string\n                      gmsaCredentialSpecName:\n                        description: GMSACredentialSpecName is the name of the GMSA credential spec to use.\n                        type: string\n                      hostProcess:\n                        description: |-\n                          HostProcess determines if a container should be run as a 'Host Process' container.\n                          All of a Pod's containers must have the same effective HostProcess value\n                          (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).\n                          In addition, if HostProcess is true then HostNetwork must also be set to true.\n                        type: boolean\n                      runAsUserName:\n                        description: |-\n                          The UserName in Windows to run the entrypoint of the container process.\n                          Defaults to the user specified in image metadata if unspecified.\n                          May also be set in PodSecurityContext. If set in both SecurityContext and\n                          PodSecurityContext, the value specified in SecurityContext takes precedence.\n                        type: string\n                    type: object\n                type: object\n              serviceAccountName:\n                description: |-\n                  ServiceAccountName is the name of the ServiceAccount to use to run the\n                  Prometheus Pods.\n                type: string\n              serviceDiscoveryRole:\n                description: |-\n                  Defines the service discovery role used to discover targets from\n                  `ServiceMonitor` objects and Alertmanager endpoints.\n\n                  If set, the value should be either \"Endpoints\" or \"EndpointSlice\".\n                  If unset, the operator assumes the \"Endpoints\" role.\n                enum:\n                - Endpoints\n                - EndpointSlice\n                type: string\n              serviceMonitorNamespaceSelector:\n                description: |-\n                  Namespaces to match for ServicedMonitors discovery. An empty label selector\n                  matches all namespaces. A null label selector (default value) matches the current\n                  namespace only.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              serviceMonitorSelector:\n                description: |-\n                  ServiceMonitors to be selected for target discovery. An empty label\n                  selector matches all objects. A null label selector matches no objects.\n\n                  If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector`\n                  and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged.\n                  The Prometheus operator will ensure that the Prometheus configuration's\n                  Secret exists, but it is the responsibility of the user to provide the raw\n                  gzipped Prometheus configuration under the `prometheus.yaml.gz` key.\n                  This behavior is *deprecated* and will be removed in the next major version\n                  of the custom resource definition. It is recommended to use\n                  `spec.additionalScrapeConfigs` instead.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              serviceName:\n                description: |-\n                  The name of the service name used by the underlying StatefulSet(s) as the governing service.\n                  If defined, the Service  must be created before the Prometheus/PrometheusAgent resource in the same namespace and it must define a selector that matches the pod labels.\n                  If empty, the operator will create and manage a headless service named `prometheus-operated` for Prometheus resources,\n                  or `prometheus-agent-operated` for PrometheusAgent resources.\n                  When deploying multiple Prometheus/PrometheusAgent resources in the same namespace, it is recommended to specify a different value for each.\n                  See https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id for more details.\n                minLength: 1\n                type: string\n              sha:\n                description: 'Deprecated: use ''spec.image'' instead. The image''s digest can be specified as part of the image name.'\n                type: string\n              shardRetentionPolicy:\n                description: |-\n                  ShardRetentionPolicy defines the retention policy for the Prometheus shards.\n                  (Alpha) Using this field requires the 'PrometheusShardRetentionPolicy' feature gate to be enabled.\n\n                  The final goals for this feature can be seen at https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/proposals/202310-shard-autoscaling.md#graceful-scale-down-of-prometheus-servers,\n                  however, the feature is not yet fully implemented in this PR. The limitation being:\n                  * Retention duration is not settable, for now, shards are retained forever.\n                properties:\n                  retain:\n                    description: |-\n                      Defines the config for retention when the retention policy is set to `Retain`.\n                      This field is ineffective as of now.\n                    properties:\n                      retentionPeriod:\n                        description: |-\n                          Duration is a valid time duration that can be parsed by Prometheus model.ParseDuration() function.\n                          Supported units: y, w, d, h, m, s, ms\n                          Examples: `30s`, `1m`, `1h20m15s`, `15d`\n                        pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                        type: string\n                    required:\n                    - retentionPeriod\n                    type: object\n                  whenScaled:\n                    description: |-\n                      Defines the retention policy when the Prometheus shards are scaled down.\n                      * `Delete`, the operator will delete the pods from the scaled-down shard(s).\n                      * `Retain`, the operator will keep the pods from the scaled-down shard(s), so the data can still be queried.\n\n                      If not defined, the operator assumes the `Delete` value.\n                    enum:\n                    - Retain\n                    - Delete\n                    type: string\n                type: object\n              shards:\n                description: |-\n                  Number of shards to distribute the scraped targets onto.\n\n                  `spec.replicas` multiplied by `spec.shards` is the total number of Pods\n                  being created.\n\n                  When not defined, the operator assumes only one shard.\n\n                  Note that scaling down shards will not reshard data onto the remaining\n                  instances, it must be manually moved. Increasing shards will not reshard\n                  data either but it will continue to be available from the same\n                  instances. To query globally, use either\n                  * Thanos sidecar + querier for query federation and Thanos Ruler for rules.\n                  * Remote-write to send metrics to a central location.\n\n                  By default, the sharding of targets is performed on:\n                  * The `__address__` target's metadata label for PodMonitor,\n                  ServiceMonitor and ScrapeConfig resources.\n                  * The `__param_target__` label for Probe resources.\n\n                  Users can define their own sharding implementation by setting the\n                  `__tmp_hash` label during the target discovery with relabeling\n                  configuration (either in the monitoring resources or via scrape class).\n\n                  You can also disable sharding on a specific target by setting the\n                  `__tmp_disable_sharding` label with relabeling configuration. When\n                  the label value isn't empty, all Prometheus shards will scrape the target.\n                format: int32\n                type: integer\n              storage:\n                description: Storage defines the storage used by Prometheus.\n                properties:\n                  disableMountSubPath:\n                    description: 'Deprecated: subPath usage will be removed in a future release.'\n                    type: boolean\n                  emptyDir:\n                    description: |-\n                      EmptyDirVolumeSource to be used by the StatefulSet.\n                      If specified, it takes precedence over `ephemeral` and `volumeClaimTemplate`.\n                      More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir\n                    properties:\n                      medium:\n                        description: |-\n                          medium represents what type of storage medium should back this directory.\n                          The default is \"\" which means to use the node's default medium.\n                          Must be an empty string (default) or Memory.\n                          More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                        type: string\n                      sizeLimit:\n                        anyOf:\n                        - type: integer\n                        - type: string\n                        description: |-\n                          sizeLimit is the total amount of local storage required for this EmptyDir volume.\n                          The size limit is also applicable for memory medium.\n                          The maximum usage on memory medium EmptyDir would be the minimum value between\n                          the SizeLimit specified here and the sum of memory limits of all containers in a pod.\n                          The default is nil which means that the limit is undefined.\n                          More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                        pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                        x-kubernetes-int-or-string: true\n                    type: object\n                  ephemeral:\n                    description: |-\n                      EphemeralVolumeSource to be used by the StatefulSet.\n                      This is a beta field in k8s 1.21 and GA in 1.15.\n                      For lower versions, starting with k8s 1.19, it requires enabling the GenericEphemeralVolume feature gate.\n                      More info: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes\n                    properties:\n                      volumeClaimTemplate:\n                        description: |-\n                          Will be used to create a stand-alone PVC to provision the volume.\n                          The pod in which this EphemeralVolumeSource is embedded will be the\n                          owner of the PVC, i.e. the PVC will be deleted together with the\n                          pod.  The name of the PVC will be `<pod name>-<volume name>` where\n                          `<volume name>` is the name from the `PodSpec.Volumes` array\n                          entry. Pod validation will reject the pod if the concatenated name\n                          is not valid for a PVC (for example, too long).\n\n                          An existing PVC with that name that is not owned by the pod\n                          will *not* be used for the pod to avoid using an unrelated\n                          volume by mistake. Starting the pod is then blocked until\n                          the unrelated PVC is removed. If such a pre-created PVC is\n                          meant to be used by the pod, the PVC has to updated with an\n                          owner reference to the pod once the pod exists. Normally\n                          this should not be necessary, but it may be useful when\n                          manually reconstructing a broken cluster.\n\n                          This field is read-only and no changes will be made by Kubernetes\n                          to the PVC after it has been created.\n\n                          Required, must not be nil.\n                        properties:\n                          metadata:\n                            description: |-\n                              May contain labels and annotations that will be copied into the PVC\n                              when creating it. No other fields are allowed and will be rejected during\n                              validation.\n                            type: object\n                          spec:\n                            description: |-\n                              The specification for the PersistentVolumeClaim. The entire content is\n                              copied unchanged into the PVC that gets created from this\n                              template. The same fields as in a PersistentVolumeClaim\n                              are also valid here.\n                            properties:\n                              accessModes:\n                                description: |-\n                                  accessModes contains the desired access modes the volume should have.\n                                  More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                                items:\n                                  type: string\n                                type: array\n                                x-kubernetes-list-type: atomic\n                              dataSource:\n                                description: |-\n                                  dataSource field can be used to specify either:\n                                  * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n                                  * An existing PVC (PersistentVolumeClaim)\n                                  If the provisioner or an external controller can support the specified data source,\n                                  it will create a new volume based on the contents of the specified data source.\n                                  When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\n                                  and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\n                                  If the namespace is specified, then dataSourceRef will not be copied to dataSource.\n                                properties:\n                                  apiGroup:\n                                    description: |-\n                                      APIGroup is the group for the resource being referenced.\n                                      If APIGroup is not specified, the specified Kind must be in the core API group.\n                                      For any other third-party types, APIGroup is required.\n                                    type: string\n                                  kind:\n                                    description: Kind is the type of resource being referenced\n                                    type: string\n                                  name:\n                                    description: Name is the name of resource being referenced\n                                    type: string\n                                required:\n                                - kind\n                                - name\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              dataSourceRef:\n                                description: |-\n                                  dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\n                                  volume is desired. This may be any object from a non-empty API group (non\n                                  core object) or a PersistentVolumeClaim object.\n                                  When this field is specified, volume binding will only succeed if the type of\n                                  the specified object matches some installed volume populator or dynamic\n                                  provisioner.\n                                  This field will replace the functionality of the dataSource field and as such\n                                  if both fields are non-empty, they must have the same value. For backwards\n                                  compatibility, when namespace isn't specified in dataSourceRef,\n                                  both fields (dataSource and dataSourceRef) will be set to the same\n                                  value automatically if one of them is empty and the other is non-empty.\n                                  When namespace is specified in dataSourceRef,\n                                  dataSource isn't set to the same value and must be empty.\n                                  There are three important differences between dataSource and dataSourceRef:\n                                  * While dataSource only allows two specific types of objects, dataSourceRef\n                                    allows any non-core object, as well as PersistentVolumeClaim objects.\n                                  * While dataSource ignores disallowed values (dropping them), dataSourceRef\n                                    preserves all values, and generates an error if a disallowed value is\n                                    specified.\n                                  * While dataSource only allows local objects, dataSourceRef allows objects\n                                    in any namespaces.\n                                  (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n                                  (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                properties:\n                                  apiGroup:\n                                    description: |-\n                                      APIGroup is the group for the resource being referenced.\n                                      If APIGroup is not specified, the specified Kind must be in the core API group.\n                                      For any other third-party types, APIGroup is required.\n                                    type: string\n                                  kind:\n                                    description: Kind is the type of resource being referenced\n                                    type: string\n                                  name:\n                                    description: Name is the name of resource being referenced\n                                    type: string\n                                  namespace:\n                                    description: |-\n                                      Namespace is the namespace of resource being referenced\n                                      Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n                                      (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                    type: string\n                                required:\n                                - kind\n                                - name\n                                type: object\n                              resources:\n                                description: |-\n                                  resources represents the minimum resources the volume should have.\n                                  If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\n                                  that are lower than previous value but must still be higher than capacity recorded in the\n                                  status field of the claim.\n                                  More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources\n                                properties:\n                                  limits:\n                                    additionalProperties:\n                                      anyOf:\n                                      - type: integer\n                                      - type: string\n                                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                      x-kubernetes-int-or-string: true\n                                    description: |-\n                                      Limits describes the maximum amount of compute resources allowed.\n                                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                    type: object\n                                  requests:\n                                    additionalProperties:\n                                      anyOf:\n                                      - type: integer\n                                      - type: string\n                                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                      x-kubernetes-int-or-string: true\n                                    description: |-\n                                      Requests describes the minimum amount of compute resources required.\n                                      If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                                      otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                    type: object\n                                type: object\n                              selector:\n                                description: selector is a label query over volumes to consider for binding.\n                                properties:\n                                  matchExpressions:\n                                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                    items:\n                                      description: |-\n                                        A label selector requirement is a selector that contains values, a key, and an operator that\n                                        relates the key and values.\n                                      properties:\n                                        key:\n                                          description: key is the label key that the selector applies to.\n                                          type: string\n                                        operator:\n                                          description: |-\n                                            operator represents a key's relationship to a set of values.\n                                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                                          type: string\n                                        values:\n                                          description: |-\n                                            values is an array of string values. If the operator is In or NotIn,\n                                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                            the values array must be empty. This array is replaced during a strategic\n                                            merge patch.\n                                          items:\n                                            type: string\n                                          type: array\n                                          x-kubernetes-list-type: atomic\n                                      required:\n                                      - key\n                                      - operator\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                  matchLabels:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                    type: object\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              storageClassName:\n                                description: |-\n                                  storageClassName is the name of the StorageClass required by the claim.\n                                  More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1\n                                type: string\n                              volumeAttributesClassName:\n                                description: |-\n                                  volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\n                                  If specified, the CSI driver will create or update the volume with the attributes defined\n                                  in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\n                                  it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\n                                  will be applied to the claim but it's not allowed to reset this field to empty string once it is set.\n                                  If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\n                                  will be set by the persistentvolume controller if it exists.\n                                  If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\n                                  set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\n                                  exists.\n                                  More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n                                  (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).\n                                type: string\n                              volumeMode:\n                                description: |-\n                                  volumeMode defines what type of volume is required by the claim.\n                                  Value of Filesystem is implied when not included in claim spec.\n                                type: string\n                              volumeName:\n                                description: volumeName is the binding reference to the PersistentVolume backing this claim.\n                                type: string\n                            type: object\n                        required:\n                        - spec\n                        type: object\n                    type: object\n                  volumeClaimTemplate:\n                    description: |-\n                      Defines the PVC spec to be used by the Prometheus StatefulSets.\n                      The easiest way to use a volume that cannot be automatically provisioned\n                      is to use a label selector alongside manually created PersistentVolumes.\n                    properties:\n                      apiVersion:\n                        description: |-\n                          APIVersion defines the versioned schema of this representation of an object.\n                          Servers should convert recognized schemas to the latest internal value, and\n                          may reject unrecognized values.\n                          More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n                        type: string\n                      kind:\n                        description: |-\n                          Kind is a string value representing the REST resource this object represents.\n                          Servers may infer this from the endpoint the client submits requests to.\n                          Cannot be updated.\n                          In CamelCase.\n                          More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n                        type: string\n                      metadata:\n                        description: EmbeddedMetadata contains metadata relevant to an EmbeddedResource.\n                        properties:\n                          annotations:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              Annotations is an unstructured key value map stored with a resource that may be\n                              set by external tools to store and retrieve arbitrary metadata. They are not\n                              queryable and should be preserved when modifying objects.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/\n                            type: object\n                          labels:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              Map of string keys and values that can be used to organize and categorize\n                              (scope and select) objects. May match selectors of replication controllers\n                              and services.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/\n                            type: object\n                          name:\n                            description: |-\n                              Name must be unique within a namespace. Is required when creating resources, although\n                              some resources may allow a client to request the generation of an appropriate name\n                              automatically. Name is primarily intended for creation idempotence and configuration\n                              definition.\n                              Cannot be updated.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\n                            type: string\n                        type: object\n                      spec:\n                        description: |-\n                          Defines the desired characteristics of a volume requested by a pod author.\n                          More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims\n                        properties:\n                          accessModes:\n                            description: |-\n                              accessModes contains the desired access modes the volume should have.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                            items:\n                              type: string\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          dataSource:\n                            description: |-\n                              dataSource field can be used to specify either:\n                              * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n                              * An existing PVC (PersistentVolumeClaim)\n                              If the provisioner or an external controller can support the specified data source,\n                              it will create a new volume based on the contents of the specified data source.\n                              When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\n                              and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\n                              If the namespace is specified, then dataSourceRef will not be copied to dataSource.\n                            properties:\n                              apiGroup:\n                                description: |-\n                                  APIGroup is the group for the resource being referenced.\n                                  If APIGroup is not specified, the specified Kind must be in the core API group.\n                                  For any other third-party types, APIGroup is required.\n                                type: string\n                              kind:\n                                description: Kind is the type of resource being referenced\n                                type: string\n                              name:\n                                description: Name is the name of resource being referenced\n                                type: string\n                            required:\n                            - kind\n                            - name\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          dataSourceRef:\n                            description: |-\n                              dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\n                              volume is desired. This may be any object from a non-empty API group (non\n                              core object) or a PersistentVolumeClaim object.\n                              When this field is specified, volume binding will only succeed if the type of\n                              the specified object matches some installed volume populator or dynamic\n                              provisioner.\n                              This field will replace the functionality of the dataSource field and as such\n                              if both fields are non-empty, they must have the same value. For backwards\n                              compatibility, when namespace isn't specified in dataSourceRef,\n                              both fields (dataSource and dataSourceRef) will be set to the same\n                              value automatically if one of them is empty and the other is non-empty.\n                              When namespace is specified in dataSourceRef,\n                              dataSource isn't set to the same value and must be empty.\n                              There are three important differences between dataSource and dataSourceRef:\n                              * While dataSource only allows two specific types of objects, dataSourceRef\n                                allows any non-core object, as well as PersistentVolumeClaim objects.\n                              * While dataSource ignores disallowed values (dropping them), dataSourceRef\n                                preserves all values, and generates an error if a disallowed value is\n                                specified.\n                              * While dataSource only allows local objects, dataSourceRef allows objects\n                                in any namespaces.\n                              (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n                              (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                            properties:\n                              apiGroup:\n                                description: |-\n                                  APIGroup is the group for the resource being referenced.\n                                  If APIGroup is not specified, the specified Kind must be in the core API group.\n                                  For any other third-party types, APIGroup is required.\n                                type: string\n                              kind:\n                                description: Kind is the type of resource being referenced\n                                type: string\n                              name:\n                                description: Name is the name of resource being referenced\n                                type: string\n                              namespace:\n                                description: |-\n                                  Namespace is the namespace of resource being referenced\n                                  Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n                                  (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                type: string\n                            required:\n                            - kind\n                            - name\n                            type: object\n                          resources:\n                            description: |-\n                              resources represents the minimum resources the volume should have.\n                              If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\n                              that are lower than previous value but must still be higher than capacity recorded in the\n                              status field of the claim.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources\n                            properties:\n                              limits:\n                                additionalProperties:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                  x-kubernetes-int-or-string: true\n                                description: |-\n                                  Limits describes the maximum amount of compute resources allowed.\n                                  More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                type: object\n                              requests:\n                                additionalProperties:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                  x-kubernetes-int-or-string: true\n                                description: |-\n                                  Requests describes the minimum amount of compute resources required.\n                                  If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                                  otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                                  More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                type: object\n                            type: object\n                          selector:\n                            description: selector is a label query over volumes to consider for binding.\n                            properties:\n                              matchExpressions:\n                                description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                items:\n                                  description: |-\n                                    A label selector requirement is a selector that contains values, a key, and an operator that\n                                    relates the key and values.\n                                  properties:\n                                    key:\n                                      description: key is the label key that the selector applies to.\n                                      type: string\n                                    operator:\n                                      description: |-\n                                        operator represents a key's relationship to a set of values.\n                                        Valid operators are In, NotIn, Exists and DoesNotExist.\n                                      type: string\n                                    values:\n                                      description: |-\n                                        values is an array of string values. If the operator is In or NotIn,\n                                        the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                        the values array must be empty. This array is replaced during a strategic\n                                        merge patch.\n                                      items:\n                                        type: string\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                  required:\n                                  - key\n                                  - operator\n                                  type: object\n                                type: array\n                                x-kubernetes-list-type: atomic\n                              matchLabels:\n                                additionalProperties:\n                                  type: string\n                                description: |-\n                                  matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                  map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                  operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                type: object\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          storageClassName:\n                            description: |-\n                              storageClassName is the name of the StorageClass required by the claim.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1\n                            type: string\n                          volumeAttributesClassName:\n                            description: |-\n                              volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\n                              If specified, the CSI driver will create or update the volume with the attributes defined\n                              in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\n                              it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\n                              will be applied to the claim but it's not allowed to reset this field to empty string once it is set.\n                              If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\n                              will be set by the persistentvolume controller if it exists.\n                              If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\n                              set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\n                              exists.\n                              More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n                              (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).\n                            type: string\n                          volumeMode:\n                            description: |-\n                              volumeMode defines what type of volume is required by the claim.\n                              Value of Filesystem is implied when not included in claim spec.\n                            type: string\n                          volumeName:\n                            description: volumeName is the binding reference to the PersistentVolume backing this claim.\n                            type: string\n                        type: object\n                      status:\n                        description: 'Deprecated: this field is never set.'\n                        properties:\n                          accessModes:\n                            description: |-\n                              accessModes contains the actual access modes the volume backing the PVC has.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                            items:\n                              type: string\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          allocatedResourceStatuses:\n                            additionalProperties:\n                              description: |-\n                                When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource\n                                that it does not recognizes, then it should ignore that update and let other controllers\n                                handle it.\n                              type: string\n                            description: \"allocatedResourceStatuses stores status of resource being resized for the given PVC.\\nKey names follow standard Kubernetes label syntax. Valid values are either:\\n\\t* Un-prefixed keys:\\n\\t\\t- storage - the capacity of the volume.\\n\\t* Custom resources must use implementation-defined prefixed names such as \\\"example.com/my-custom-resource\\\"\\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\\nreserved and hence may not be used.\\n\\nClaimResourceStatus can be in any of following states:\\n\\t- ControllerResizeInProgress:\\n\\t\\tState set when resize controller starts resizing the volume in control-plane.\\n\\t- ControllerResizeFailed:\\n\\t\\tState set when resize has failed in resize controller with a terminal error.\\n\\t- NodeResizePending:\\n\\t\\tState set when resize controller has finished resizing the volume but further resizing of\\n\\t\\tvolume is needed on the node.\\n\\t- NodeResizeInProgress:\\n\\t\\tState set when kubelet starts resizing the volume.\\n\\t- NodeResizeFailed:\\n\\t\\tState set when resizing has failed in kubelet with a terminal error. Transient errors don't set\\n\\t\\tNodeResizeFailed.\\nFor example: if expanding a PVC for more capacity - this field can be one of the following states:\\n\\t- pvc.status.allocatedResourceStatus['storage'] = \\\"ControllerResizeInProgress\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"ControllerResizeFailed\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"NodeResizePending\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"NodeResizeInProgress\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"NodeResizeFailed\\\"\\nWhen this field is not set, it means that no resize operation is in progress for the given PVC.\\n\\nA controller that receives PVC update with previously unknown resourceName or ClaimResourceStatus\\nshould ignore the update for the purpose it was designed. For example - a controller that\\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\\nresources associated with PVC.\\n\\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.\"\n                            type: object\n                            x-kubernetes-map-type: granular\n                          allocatedResources:\n                            additionalProperties:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                              x-kubernetes-int-or-string: true\n                            description: \"allocatedResources tracks the resources allocated to a PVC including its capacity.\\nKey names follow standard Kubernetes label syntax. Valid values are either:\\n\\t* Un-prefixed keys:\\n\\t\\t- storage - the capacity of the volume.\\n\\t* Custom resources must use implementation-defined prefixed names such as \\\"example.com/my-custom-resource\\\"\\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\\nreserved and hence may not be used.\\n\\nCapacity reported here may be larger than the actual capacity when a volume expansion operation\\nis requested.\\nFor storage quota, the larger value from allocatedResources and PVC.spec.resources is used.\\nIf allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.\\nIf a volume expansion capacity request is lowered, allocatedResources is only\\nlowered if there are no expansion operations in progress and if the actual volume capacity\\nis equal or lower than the requested capacity.\\n\\nA controller that receives PVC update with previously unknown resourceName\\nshould ignore the update for the purpose it was designed. For example - a controller that\\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\\nresources associated with PVC.\\n\\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.\"\n                            type: object\n                          capacity:\n                            additionalProperties:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                              x-kubernetes-int-or-string: true\n                            description: capacity represents the actual resources of the underlying volume.\n                            type: object\n                          conditions:\n                            description: |-\n                              conditions is the current Condition of persistent volume claim. If underlying persistent volume is being\n                              resized then the Condition will be set to 'Resizing'.\n                            items:\n                              description: PersistentVolumeClaimCondition contains details about state of pvc\n                              properties:\n                                lastProbeTime:\n                                  description: lastProbeTime is the time we probed the condition.\n                                  format: date-time\n                                  type: string\n                                lastTransitionTime:\n                                  description: lastTransitionTime is the time the condition transitioned from one status to another.\n                                  format: date-time\n                                  type: string\n                                message:\n                                  description: message is the human-readable message indicating details about last transition.\n                                  type: string\n                                reason:\n                                  description: |-\n                                    reason is a unique, this should be a short, machine understandable string that gives the reason\n                                    for condition's last transition. If it reports \"Resizing\" that means the underlying\n                                    persistent volume is being resized.\n                                  type: string\n                                status:\n                                  description: |-\n                                    Status is the status of the condition.\n                                    Can be True, False, Unknown.\n                                    More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=state%20of%20pvc-,conditions.status,-(string)%2C%20required\n                                  type: string\n                                type:\n                                  description: |-\n                                    Type is the type of the condition.\n                                    More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=set%20to%20%27ResizeStarted%27.-,PersistentVolumeClaimCondition,-contains%20details%20about\n                                  type: string\n                              required:\n                              - status\n                              - type\n                              type: object\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - type\n                            x-kubernetes-list-type: map\n                          currentVolumeAttributesClassName:\n                            description: |-\n                              currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using.\n                              When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim\n                              This is a beta field and requires enabling VolumeAttributesClass feature (off by default).\n                            type: string\n                          modifyVolumeStatus:\n                            description: |-\n                              ModifyVolumeStatus represents the status object of ControllerModifyVolume operation.\n                              When this is unset, there is no ModifyVolume operation being attempted.\n                              This is a beta field and requires enabling VolumeAttributesClass feature (off by default).\n                            properties:\n                              status:\n                                description: \"status is the status of the ControllerModifyVolume operation. It can be in any of following states:\\n - Pending\\n   Pending indicates that the PersistentVolumeClaim cannot be modified due to unmet requirements, such as\\n   the specified VolumeAttributesClass not existing.\\n - InProgress\\n   InProgress indicates that the volume is being modified.\\n - Infeasible\\n  Infeasible indicates that the request has been rejected as invalid by the CSI driver. To\\n\\t  resolve the error, a valid VolumeAttributesClass needs to be specified.\\nNote: New statuses can be added in the future. Consumers should check for unknown statuses and fail appropriately.\"\n                                type: string\n                              targetVolumeAttributesClassName:\n                                description: targetVolumeAttributesClassName is the name of the VolumeAttributesClass the PVC currently being reconciled\n                                type: string\n                            required:\n                            - status\n                            type: object\n                          phase:\n                            description: phase represents the current phase of PersistentVolumeClaim.\n                            type: string\n                        type: object\n                    type: object\n                type: object\n              tag:\n                description: 'Deprecated: use ''spec.image'' instead. The image''s tag can be specified as part of the image name.'\n                type: string\n              targetLimit:\n                description: |-\n                  TargetLimit defines a limit on the number of scraped targets that will be accepted.\n                  Only valid in Prometheus versions 2.45.0 and newer.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedTargetLimit.\n                format: int64\n                type: integer\n              terminationGracePeriodSeconds:\n                description: |-\n                  Optional duration in seconds the pod needs to terminate gracefully.\n                  Value must be non-negative integer. The value zero indicates stop immediately via\n                  the kill signal (no opportunity to shut down) which may lead to data corruption.\n\n                  Defaults to 600 seconds.\n                format: int64\n                minimum: 0\n                type: integer\n              thanos:\n                description: Defines the configuration of the optional Thanos sidecar.\n                properties:\n                  additionalArgs:\n                    description: |-\n                      AdditionalArgs allows setting additional arguments for the Thanos container.\n                      The arguments are passed as-is to the Thanos container which may cause issues\n                      if they are invalid or not supported the given Thanos version.\n                      In case of an argument conflict (e.g. an argument which is already set by the\n                      operator itself) or when providing an invalid argument, the reconciliation will\n                      fail and an error will be logged.\n                    items:\n                      description: Argument as part of the AdditionalArgs list.\n                      properties:\n                        name:\n                          description: Name of the argument, e.g. \"scrape.discovery-reload-interval\".\n                          minLength: 1\n                          type: string\n                        value:\n                          description: Argument value, e.g. 30s. Can be empty for name-only arguments (e.g. --storage.tsdb.no-lockfile)\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    type: array\n                  baseImage:\n                    description: 'Deprecated: use ''image'' instead.'\n                    type: string\n                  blockSize:\n                    default: 2h\n                    description: |-\n                      BlockDuration controls the size of TSDB blocks produced by Prometheus.\n                      The default value is 2h to match the upstream Prometheus defaults.\n\n                      WARNING: Changing the block duration can impact the performance and\n                      efficiency of the entire Prometheus/Thanos stack due to how it interacts\n                      with memory and Thanos compactors. It is recommended to keep this value\n                      set to a multiple of 120 times your longest scrape or rule interval. For\n                      example, 30s * 120 = 1h.\n                    pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                    type: string\n                  getConfigInterval:\n                    description: How often to retrieve the Prometheus configuration.\n                    pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                    type: string\n                  getConfigTimeout:\n                    description: Maximum time to wait when retrieving the Prometheus configuration.\n                    pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                    type: string\n                  grpcListenLocal:\n                    description: |-\n                      When true, the Thanos sidecar listens on the loopback interface instead\n                      of the Pod IP's address for the gRPC endpoints.\n\n                      It has no effect if `listenLocal` is true.\n                    type: boolean\n                  grpcServerTlsConfig:\n                    description: |-\n                      Configures the TLS parameters for the gRPC server providing the StoreAPI.\n\n                      Note: Currently only the `caFile`, `certFile`, and `keyFile` fields are supported.\n                    properties:\n                      ca:\n                        description: Certificate authority used when verifying server certificates.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      caFile:\n                        description: Path to the CA cert in the Prometheus container to use for the targets.\n                        type: string\n                      cert:\n                        description: Client certificate to present when doing client-authentication.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      certFile:\n                        description: Path to the client cert file in the Prometheus container for the targets.\n                        type: string\n                      insecureSkipVerify:\n                        description: Disable target certificate validation.\n                        type: boolean\n                      keyFile:\n                        description: Path to the client key file in the Prometheus container for the targets.\n                        type: string\n                      keySecret:\n                        description: Secret containing the client key file for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: |-\n                          Maximum acceptable TLS version.\n\n                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      minVersion:\n                        description: |-\n                          Minimum acceptable TLS version.\n\n                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      serverName:\n                        description: Used to verify the hostname for the targets.\n                        type: string\n                    type: object\n                  httpListenLocal:\n                    description: |-\n                      When true, the Thanos sidecar listens on the loopback interface instead\n                      of the Pod IP's address for the HTTP endpoints.\n\n                      It has no effect if `listenLocal` is true.\n                    type: boolean\n                  image:\n                    description: |-\n                      Container image name for Thanos. If specified, it takes precedence over\n                      the `spec.thanos.baseImage`, `spec.thanos.tag` and `spec.thanos.sha`\n                      fields.\n\n                      Specifying `spec.thanos.version` is still necessary to ensure the\n                      Prometheus Operator knows which version of Thanos is being configured.\n\n                      If neither `spec.thanos.image` nor `spec.thanos.baseImage` are defined,\n                      the operator will use the latest upstream version of Thanos available at\n                      the time when the operator was released.\n                    type: string\n                  listenLocal:\n                    description: 'Deprecated: use `grpcListenLocal` and `httpListenLocal` instead.'\n                    type: boolean\n                  logFormat:\n                    description: Log format for the Thanos sidecar.\n                    enum:\n                    - \"\"\n                    - logfmt\n                    - json\n                    type: string\n                  logLevel:\n                    description: Log level for the Thanos sidecar.\n                    enum:\n                    - \"\"\n                    - debug\n                    - info\n                    - warn\n                    - error\n                    type: string\n                  minTime:\n                    description: |-\n                      Defines the start of time range limit served by the Thanos sidecar's StoreAPI.\n                      The field's value should be a constant time in RFC3339 format or a time\n                      duration relative to current time, such as -1d or 2h45m. Valid duration\n                      units are ms, s, m, h, d, w, y.\n                    type: string\n                  objectStorageConfig:\n                    description: |-\n                      Defines the Thanos sidecar's configuration to upload TSDB blocks to object storage.\n\n                      More info: https://thanos.io/tip/thanos/storage.md/\n\n                      objectStorageConfigFile takes precedence over this field.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  objectStorageConfigFile:\n                    description: |-\n                      Defines the Thanos sidecar's configuration file to upload TSDB blocks to object storage.\n\n                      More info: https://thanos.io/tip/thanos/storage.md/\n\n                      This field takes precedence over objectStorageConfig.\n                    type: string\n                  readyTimeout:\n                    description: |-\n                      ReadyTimeout is the maximum time that the Thanos sidecar will wait for\n                      Prometheus to start.\n                    pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                    type: string\n                  resources:\n                    description: Defines the resources requests and limits of the Thanos sidecar.\n                    properties:\n                      claims:\n                        description: |-\n                          Claims lists the names of resources, defined in spec.resourceClaims,\n                          that are used by this container.\n\n                          This is an alpha field and requires enabling the\n                          DynamicResourceAllocation feature gate.\n\n                          This field is immutable. It can only be set for containers.\n                        items:\n                          description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                          properties:\n                            name:\n                              description: |-\n                                Name must match the name of one entry in pod.spec.resourceClaims of\n                                the Pod where this field is used. It makes that resource available\n                                inside a container.\n                              type: string\n                            request:\n                              description: |-\n                                Request is the name chosen for a request in the referenced claim.\n                                If empty, everything from the claim is made available, otherwise\n                                only the result of this request.\n                              type: string\n                          required:\n                          - name\n                          type: object\n                        type: array\n                        x-kubernetes-list-map-keys:\n                        - name\n                        x-kubernetes-list-type: map\n                      limits:\n                        additionalProperties:\n                          anyOf:\n                          - type: integer\n                          - type: string\n                          pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                          x-kubernetes-int-or-string: true\n                        description: |-\n                          Limits describes the maximum amount of compute resources allowed.\n                          More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                        type: object\n                      requests:\n                        additionalProperties:\n                          anyOf:\n                          - type: integer\n                          - type: string\n                          pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                          x-kubernetes-int-or-string: true\n                        description: |-\n                          Requests describes the minimum amount of compute resources required.\n                          If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                          otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                          More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                        type: object\n                    type: object\n                  sha:\n                    description: 'Deprecated: use ''image'' instead.  The image digest can be specified as part of the image name.'\n                    type: string\n                  tag:\n                    description: 'Deprecated: use ''image'' instead. The image''s tag can be specified as as part of the image name.'\n                    type: string\n                  tracingConfig:\n                    description: |-\n                      Defines the tracing configuration for the Thanos sidecar.\n\n                      `tracingConfigFile` takes precedence over this field.\n\n                      More info: https://thanos.io/tip/thanos/tracing.md/\n\n                      This is an *experimental feature*, it may change in any upcoming release\n                      in a breaking way.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  tracingConfigFile:\n                    description: |-\n                      Defines the tracing configuration file for the Thanos sidecar.\n\n                      This field takes precedence over `tracingConfig`.\n\n                      More info: https://thanos.io/tip/thanos/tracing.md/\n\n                      This is an *experimental feature*, it may change in any upcoming release\n                      in a breaking way.\n                    type: string\n                  version:\n                    description: |-\n                      Version of Thanos being deployed. The operator uses this information\n                      to generate the Prometheus StatefulSet + configuration files.\n\n                      If not specified, the operator assumes the latest upstream release of\n                      Thanos available at the time when the version of the operator was\n                      released.\n                    type: string\n                  volumeMounts:\n                    description: |-\n                      VolumeMounts allows configuration of additional VolumeMounts for Thanos.\n                      VolumeMounts specified will be appended to other VolumeMounts in the\n                      'thanos-sidecar' container.\n                    items:\n                      description: VolumeMount describes a mounting of a Volume within a container.\n                      properties:\n                        mountPath:\n                          description: |-\n                            Path within the container at which the volume should be mounted.  Must\n                            not contain ':'.\n                          type: string\n                        mountPropagation:\n                          description: |-\n                            mountPropagation determines how mounts are propagated from the host\n                            to container and the other way around.\n                            When not set, MountPropagationNone is used.\n                            This field is beta in 1.10.\n                            When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                            (which defaults to None).\n                          type: string\n                        name:\n                          description: This must match the Name of a Volume.\n                          type: string\n                        readOnly:\n                          description: |-\n                            Mounted read-only if true, read-write otherwise (false or unspecified).\n                            Defaults to false.\n                          type: boolean\n                        recursiveReadOnly:\n                          description: |-\n                            RecursiveReadOnly specifies whether read-only mounts should be handled\n                            recursively.\n\n                            If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                            If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                            recursively read-only.  If this field is set to IfPossible, the mount is made\n                            recursively read-only, if it is supported by the container runtime.  If this\n                            field is set to Enabled, the mount is made recursively read-only if it is\n                            supported by the container runtime, otherwise the pod will not be started and\n                            an error will be generated to indicate the reason.\n\n                            If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                            None (or be unspecified, which defaults to None).\n\n                            If this field is not specified, it is treated as an equivalent of Disabled.\n                          type: string\n                        subPath:\n                          description: |-\n                            Path within the volume from which the container's volume should be mounted.\n                            Defaults to \"\" (volume's root).\n                          type: string\n                        subPathExpr:\n                          description: |-\n                            Expanded path within the volume from which the container's volume should be mounted.\n                            Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                            Defaults to \"\" (volume's root).\n                            SubPathExpr and SubPath are mutually exclusive.\n                          type: string\n                      required:\n                      - mountPath\n                      - name\n                      type: object\n                    type: array\n                type: object\n              tolerations:\n                description: Defines the Pods' tolerations if specified.\n                items:\n                  description: |-\n                    The pod this Toleration is attached to tolerates any taint that matches\n                    the triple <key,value,effect> using the matching operator <operator>.\n                  properties:\n                    effect:\n                      description: |-\n                        Effect indicates the taint effect to match. Empty means match all taint effects.\n                        When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.\n                      type: string\n                    key:\n                      description: |-\n                        Key is the taint key that the toleration applies to. Empty means match all taint keys.\n                        If the key is empty, operator must be Exists; this combination means to match all values and all keys.\n                      type: string\n                    operator:\n                      description: |-\n                        Operator represents a key's relationship to the value.\n                        Valid operators are Exists and Equal. Defaults to Equal.\n                        Exists is equivalent to wildcard for value, so that a pod can\n                        tolerate all taints of a particular category.\n                      type: string\n                    tolerationSeconds:\n                      description: |-\n                        TolerationSeconds represents the period of time the toleration (which must be\n                        of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,\n                        it is not set, which means tolerate the taint forever (do not evict). Zero and\n                        negative values will be treated as 0 (evict immediately) by the system.\n                      format: int64\n                      type: integer\n                    value:\n                      description: |-\n                        Value is the taint value the toleration matches to.\n                        If the operator is Exists, the value should be empty, otherwise just a regular string.\n                      type: string\n                  type: object\n                type: array\n              topologySpreadConstraints:\n                description: Defines the pod's topology spread constraints if specified.\n                items:\n                  properties:\n                    additionalLabelSelectors:\n                      description: Defines what Prometheus Operator managed labels should be added to labelSelector on the topologySpreadConstraint.\n                      enum:\n                      - OnResource\n                      - OnShard\n                      type: string\n                    labelSelector:\n                      description: |-\n                        LabelSelector is used to find matching pods.\n                        Pods that match this label selector are counted to determine the number of pods\n                        in their corresponding topology domain.\n                      properties:\n                        matchExpressions:\n                          description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                          items:\n                            description: |-\n                              A label selector requirement is a selector that contains values, a key, and an operator that\n                              relates the key and values.\n                            properties:\n                              key:\n                                description: key is the label key that the selector applies to.\n                                type: string\n                              operator:\n                                description: |-\n                                  operator represents a key's relationship to a set of values.\n                                  Valid operators are In, NotIn, Exists and DoesNotExist.\n                                type: string\n                              values:\n                                description: |-\n                                  values is an array of string values. If the operator is In or NotIn,\n                                  the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                  the values array must be empty. This array is replaced during a strategic\n                                  merge patch.\n                                items:\n                                  type: string\n                                type: array\n                                x-kubernetes-list-type: atomic\n                            required:\n                            - key\n                            - operator\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        matchLabels:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                            map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                            operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                          type: object\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    matchLabelKeys:\n                      description: |-\n                        MatchLabelKeys is a set of pod label keys to select the pods over which\n                        spreading will be calculated. The keys are used to lookup values from the\n                        incoming pod labels, those key-value labels are ANDed with labelSelector\n                        to select the group of existing pods over which spreading will be calculated\n                        for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.\n                        MatchLabelKeys cannot be set when LabelSelector isn't set.\n                        Keys that don't exist in the incoming pod labels will\n                        be ignored. A null or empty list means only match against labelSelector.\n\n                        This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default).\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    maxSkew:\n                      description: |-\n                        MaxSkew describes the degree to which pods may be unevenly distributed.\n                        When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference\n                        between the number of matching pods in the target topology and the global minimum.\n                        The global minimum is the minimum number of matching pods in an eligible domain\n                        or zero if the number of eligible domains is less than MinDomains.\n                        For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same\n                        labelSelector spread as 2/2/1:\n                        In this case, the global minimum is 1.\n                        | zone1 | zone2 | zone3 |\n                        |  P P  |  P P  |   P   |\n                        - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2;\n                        scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2)\n                        violate MaxSkew(1).\n                        - if MaxSkew is 2, incoming pod can be scheduled onto any zone.\n                        When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence\n                        to topologies that satisfy it.\n                        It's a required field. Default value is 1 and 0 is not allowed.\n                      format: int32\n                      type: integer\n                    minDomains:\n                      description: |-\n                        MinDomains indicates a minimum number of eligible domains.\n                        When the number of eligible domains with matching topology keys is less than minDomains,\n                        Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed.\n                        And when the number of eligible domains with matching topology keys equals or greater than minDomains,\n                        this value has no effect on scheduling.\n                        As a result, when the number of eligible domains is less than minDomains,\n                        scheduler won't schedule more than maxSkew Pods to those domains.\n                        If value is nil, the constraint behaves as if MinDomains is equal to 1.\n                        Valid values are integers greater than 0.\n                        When value is not nil, WhenUnsatisfiable must be DoNotSchedule.\n\n                        For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same\n                        labelSelector spread as 2/2/2:\n                        | zone1 | zone2 | zone3 |\n                        |  P P  |  P P  |  P P  |\n                        The number of domains is less than 5(MinDomains), so \"global minimum\" is treated as 0.\n                        In this situation, new pod with the same labelSelector cannot be scheduled,\n                        because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones,\n                        it will violate MaxSkew.\n                      format: int32\n                      type: integer\n                    nodeAffinityPolicy:\n                      description: |-\n                        NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector\n                        when calculating pod topology spread skew. Options are:\n                        - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations.\n                        - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.\n\n                        If this value is nil, the behavior is equivalent to the Honor policy.\n                      type: string\n                    nodeTaintsPolicy:\n                      description: |-\n                        NodeTaintsPolicy indicates how we will treat node taints when calculating\n                        pod topology spread skew. Options are:\n                        - Honor: nodes without taints, along with tainted nodes for which the incoming pod\n                        has a toleration, are included.\n                        - Ignore: node taints are ignored. All nodes are included.\n\n                        If this value is nil, the behavior is equivalent to the Ignore policy.\n                      type: string\n                    topologyKey:\n                      description: |-\n                        TopologyKey is the key of node labels. Nodes that have a label with this key\n                        and identical values are considered to be in the same topology.\n                        We consider each <key, value> as a \"bucket\", and try to put balanced number\n                        of pods into each bucket.\n                        We define a domain as a particular instance of a topology.\n                        Also, we define an eligible domain as a domain whose nodes meet the requirements of\n                        nodeAffinityPolicy and nodeTaintsPolicy.\n                        e.g. If TopologyKey is \"kubernetes.io/hostname\", each Node is a domain of that topology.\n                        And, if TopologyKey is \"topology.kubernetes.io/zone\", each zone is a domain of that topology.\n                        It's a required field.\n                      type: string\n                    whenUnsatisfiable:\n                      description: |-\n                        WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy\n                        the spread constraint.\n                        - DoNotSchedule (default) tells the scheduler not to schedule it.\n                        - ScheduleAnyway tells the scheduler to schedule the pod in any location,\n                          but giving higher precedence to topologies that would help reduce the\n                          skew.\n                        A constraint is considered \"Unsatisfiable\" for an incoming pod\n                        if and only if every possible node assignment for that pod would violate\n                        \"MaxSkew\" on some topology.\n                        For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same\n                        labelSelector spread as 3/1/1:\n                        | zone1 | zone2 | zone3 |\n                        | P P P |   P   |   P   |\n                        If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled\n                        to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies\n                        MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler\n                        won't make it *more* imbalanced.\n                        It's a required field.\n                      type: string\n                  required:\n                  - maxSkew\n                  - topologyKey\n                  - whenUnsatisfiable\n                  type: object\n                type: array\n              tracingConfig:\n                description: |-\n                  TracingConfig configures tracing in Prometheus.\n\n                  This is an *experimental feature*, it may change in any upcoming release\n                  in a breaking way.\n                properties:\n                  clientType:\n                    description: Client used to export the traces. Supported values are `http` or `grpc`.\n                    enum:\n                    - http\n                    - grpc\n                    type: string\n                  compression:\n                    description: Compression key for supported compression types. The only supported value is `gzip`.\n                    enum:\n                    - gzip\n                    type: string\n                  endpoint:\n                    description: Endpoint to send the traces to. Should be provided in format <host>:<port>.\n                    minLength: 1\n                    type: string\n                  headers:\n                    additionalProperties:\n                      type: string\n                    description: Key-value pairs to be used as headers associated with gRPC or HTTP requests.\n                    type: object\n                  insecure:\n                    description: If disabled, the client will use a secure connection.\n                    type: boolean\n                  samplingFraction:\n                    anyOf:\n                    - type: integer\n                    - type: string\n                    description: Sets the probability a given trace will be sampled. Must be a float from 0 through 1.\n                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                    x-kubernetes-int-or-string: true\n                  timeout:\n                    description: Maximum time the exporter will wait for each batch export.\n                    pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                    type: string\n                  tlsConfig:\n                    description: TLS Config to use when sending traces.\n                    properties:\n                      ca:\n                        description: Certificate authority used when verifying server certificates.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      caFile:\n                        description: Path to the CA cert in the Prometheus container to use for the targets.\n                        type: string\n                      cert:\n                        description: Client certificate to present when doing client-authentication.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      certFile:\n                        description: Path to the client cert file in the Prometheus container for the targets.\n                        type: string\n                      insecureSkipVerify:\n                        description: Disable target certificate validation.\n                        type: boolean\n                      keyFile:\n                        description: Path to the client key file in the Prometheus container for the targets.\n                        type: string\n                      keySecret:\n                        description: Secret containing the client key file for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: |-\n                          Maximum acceptable TLS version.\n\n                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      minVersion:\n                        description: |-\n                          Minimum acceptable TLS version.\n\n                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      serverName:\n                        description: Used to verify the hostname for the targets.\n                        type: string\n                    type: object\n                required:\n                - endpoint\n                type: object\n              tsdb:\n                description: |-\n                  Defines the runtime reloadable configuration of the timeseries database(TSDB).\n                  It requires Prometheus >= v2.39.0 or PrometheusAgent >= v2.54.0.\n                properties:\n                  outOfOrderTimeWindow:\n                    description: |-\n                      Configures how old an out-of-order/out-of-bounds sample can be with\n                      respect to the TSDB max time.\n\n                      An out-of-order/out-of-bounds sample is ingested into the TSDB as long as\n                      the timestamp of the sample is >= (TSDB.MaxTime - outOfOrderTimeWindow).\n\n                      This is an *experimental feature*, it may change in any upcoming release\n                      in a breaking way.\n\n                      It requires Prometheus >= v2.39.0 or PrometheusAgent >= v2.54.0.\n                    pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                    type: string\n                type: object\n              version:\n                description: |-\n                  Version of Prometheus being deployed. The operator uses this information\n                  to generate the Prometheus StatefulSet + configuration files.\n\n                  If not specified, the operator assumes the latest upstream version of\n                  Prometheus available at the time when the version of the operator was\n                  released.\n                type: string\n              volumeMounts:\n                description: |-\n                  VolumeMounts allows the configuration of additional VolumeMounts.\n\n                  VolumeMounts will be appended to other VolumeMounts in the 'prometheus'\n                  container, that are generated as a result of StorageSpec objects.\n                items:\n                  description: VolumeMount describes a mounting of a Volume within a container.\n                  properties:\n                    mountPath:\n                      description: |-\n                        Path within the container at which the volume should be mounted.  Must\n                        not contain ':'.\n                      type: string\n                    mountPropagation:\n                      description: |-\n                        mountPropagation determines how mounts are propagated from the host\n                        to container and the other way around.\n                        When not set, MountPropagationNone is used.\n                        This field is beta in 1.10.\n                        When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                        (which defaults to None).\n                      type: string\n                    name:\n                      description: This must match the Name of a Volume.\n                      type: string\n                    readOnly:\n                      description: |-\n                        Mounted read-only if true, read-write otherwise (false or unspecified).\n                        Defaults to false.\n                      type: boolean\n                    recursiveReadOnly:\n                      description: |-\n                        RecursiveReadOnly specifies whether read-only mounts should be handled\n                        recursively.\n\n                        If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                        If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                        recursively read-only.  If this field is set to IfPossible, the mount is made\n                        recursively read-only, if it is supported by the container runtime.  If this\n                        field is set to Enabled, the mount is made recursively read-only if it is\n                        supported by the container runtime, otherwise the pod will not be started and\n                        an error will be generated to indicate the reason.\n\n                        If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                        None (or be unspecified, which defaults to None).\n\n                        If this field is not specified, it is treated as an equivalent of Disabled.\n                      type: string\n                    subPath:\n                      description: |-\n                        Path within the volume from which the container's volume should be mounted.\n                        Defaults to \"\" (volume's root).\n                      type: string\n                    subPathExpr:\n                      description: |-\n                        Expanded path within the volume from which the container's volume should be mounted.\n                        Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                        Defaults to \"\" (volume's root).\n                        SubPathExpr and SubPath are mutually exclusive.\n                      type: string\n                  required:\n                  - mountPath\n                  - name\n                  type: object\n                type: array\n              volumes:\n                description: |-\n                  Volumes allows the configuration of additional volumes on the output\n                  StatefulSet definition. Volumes specified will be appended to other\n                  volumes that are generated as a result of StorageSpec objects.\n                items:\n                  description: Volume represents a named volume in a pod that may be accessed by any container in the pod.\n                  properties:\n                    awsElasticBlockStore:\n                      description: |-\n                        awsElasticBlockStore represents an AWS Disk resource that is attached to a\n                        kubelet's host machine and then exposed to the pod.\n                        Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree\n                        awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                          type: string\n                        partition:\n                          description: |-\n                            partition is the partition in the volume that you want to mount.\n                            If omitted, the default is to mount by volume name.\n                            Examples: For volume /dev/sda1, you specify the partition as \"1\".\n                            Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty).\n                          format: int32\n                          type: integer\n                        readOnly:\n                          description: |-\n                            readOnly value true will force the readOnly setting in VolumeMounts.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                          type: boolean\n                        volumeID:\n                          description: |-\n                            volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume).\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                          type: string\n                      required:\n                      - volumeID\n                      type: object\n                    azureDisk:\n                      description: |-\n                        azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.\n                        Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type\n                        are redirected to the disk.csi.azure.com CSI driver.\n                      properties:\n                        cachingMode:\n                          description: 'cachingMode is the Host Caching mode: None, Read Only, Read Write.'\n                          type: string\n                        diskName:\n                          description: diskName is the Name of the data disk in the blob storage\n                          type: string\n                        diskURI:\n                          description: diskURI is the URI of data disk in the blob storage\n                          type: string\n                        fsType:\n                          default: ext4\n                          description: |-\n                            fsType is Filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        kind:\n                          description: 'kind expected values are Shared: multiple blob disks per storage account  Dedicated: single blob disk per storage account  Managed: azure managed data disk (only in managed availability set). defaults to shared'\n                          type: string\n                        readOnly:\n                          default: false\n                          description: |-\n                            readOnly Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                      required:\n                      - diskName\n                      - diskURI\n                      type: object\n                    azureFile:\n                      description: |-\n                        azureFile represents an Azure File Service mount on the host and bind mount to the pod.\n                        Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type\n                        are redirected to the file.csi.azure.com CSI driver.\n                      properties:\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretName:\n                          description: secretName is the  name of secret that contains Azure Storage Account Name and Key\n                          type: string\n                        shareName:\n                          description: shareName is the azure share Name\n                          type: string\n                      required:\n                      - secretName\n                      - shareName\n                      type: object\n                    cephfs:\n                      description: |-\n                        cephFS represents a Ceph FS mount on the host that shares a pod's lifetime.\n                        Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported.\n                      properties:\n                        monitors:\n                          description: |-\n                            monitors is Required: Monitors is a collection of Ceph monitors\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        path:\n                          description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /'\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly is Optional: Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          type: boolean\n                        secretFile:\n                          description: |-\n                            secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          type: string\n                        secretRef:\n                          description: |-\n                            secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty.\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        user:\n                          description: |-\n                            user is optional: User is the rados user name, default is admin\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          type: string\n                      required:\n                      - monitors\n                      type: object\n                    cinder:\n                      description: |-\n                        cinder represents a cinder volume attached and mounted on kubelets host machine.\n                        Deprecated: Cinder is deprecated. All operations for the in-tree cinder type\n                        are redirected to the cinder.csi.openstack.org CSI driver.\n                        More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                            More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef is optional: points to a secret object containing parameters used to connect\n                            to OpenStack.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        volumeID:\n                          description: |-\n                            volumeID used to identify the volume in cinder.\n                            More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                          type: string\n                      required:\n                      - volumeID\n                      type: object\n                    configMap:\n                      description: configMap represents a configMap that should populate this volume\n                      properties:\n                        defaultMode:\n                          description: |-\n                            defaultMode is optional: mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                            Defaults to 0644.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        items:\n                          description: |-\n                            items if unspecified, each key-value pair in the Data field of the referenced\n                            ConfigMap will be projected into the volume as a file whose name is the\n                            key and content is the value. If specified, the listed keys will be\n                            projected into the specified paths, and unlisted keys will not be\n                            present. If a key is specified which is not present in the ConfigMap,\n                            the volume setup will error unless it is marked optional. Paths must be\n                            relative and may not contain the '..' path or start with '..'.\n                          items:\n                            description: Maps a string key to a path within a volume.\n                            properties:\n                              key:\n                                description: key is the key to project.\n                                type: string\n                              mode:\n                                description: |-\n                                  mode is Optional: mode bits used to set permissions on this file.\n                                  Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                  YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                  If not specified, the volume defaultMode will be used.\n                                  This might be in conflict with other options that affect the file\n                                  mode, like fsGroup, and the result can be other mode bits set.\n                                format: int32\n                                type: integer\n                              path:\n                                description: |-\n                                  path is the relative path of the file to map the key to.\n                                  May not be an absolute path.\n                                  May not contain the path element '..'.\n                                  May not start with the string '..'.\n                                type: string\n                            required:\n                            - key\n                            - path\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: optional specify whether the ConfigMap or its keys must be defined\n                          type: boolean\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    csi:\n                      description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers.\n                      properties:\n                        driver:\n                          description: |-\n                            driver is the name of the CSI driver that handles this volume.\n                            Consult with your admin for the correct name as registered in the cluster.\n                          type: string\n                        fsType:\n                          description: |-\n                            fsType to mount. Ex. \"ext4\", \"xfs\", \"ntfs\".\n                            If not provided, the empty value is passed to the associated CSI driver\n                            which will determine the default filesystem to apply.\n                          type: string\n                        nodePublishSecretRef:\n                          description: |-\n                            nodePublishSecretRef is a reference to the secret object containing\n                            sensitive information to pass to the CSI driver to complete the CSI\n                            NodePublishVolume and NodeUnpublishVolume calls.\n                            This field is optional, and  may be empty if no secret is required. If the\n                            secret object contains more than one secret, all secret references are passed.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        readOnly:\n                          description: |-\n                            readOnly specifies a read-only configuration for the volume.\n                            Defaults to false (read/write).\n                          type: boolean\n                        volumeAttributes:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            volumeAttributes stores driver-specific properties that are passed to the CSI\n                            driver. Consult your driver's documentation for supported values.\n                          type: object\n                      required:\n                      - driver\n                      type: object\n                    downwardAPI:\n                      description: downwardAPI represents downward API about the pod that should populate this volume\n                      properties:\n                        defaultMode:\n                          description: |-\n                            Optional: mode bits to use on created files by default. Must be a\n                            Optional: mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                            Defaults to 0644.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        items:\n                          description: Items is a list of downward API volume file\n                          items:\n                            description: DownwardAPIVolumeFile represents information to create the file containing the pod field\n                            properties:\n                              fieldRef:\n                                description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.'\n                                properties:\n                                  apiVersion:\n                                    description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                    type: string\n                                  fieldPath:\n                                    description: Path of the field to select in the specified API version.\n                                    type: string\n                                required:\n                                - fieldPath\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              mode:\n                                description: |-\n                                  Optional: mode bits used to set permissions on this file, must be an octal value\n                                  between 0000 and 0777 or a decimal value between 0 and 511.\n                                  YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                  If not specified, the volume defaultMode will be used.\n                                  This might be in conflict with other options that affect the file\n                                  mode, like fsGroup, and the result can be other mode bits set.\n                                format: int32\n                                type: integer\n                              path:\n                                description: 'Required: Path is  the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..'''\n                                type: string\n                              resourceFieldRef:\n                                description: |-\n                                  Selects a resource of the container: only resources limits and requests\n                                  (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.\n                                properties:\n                                  containerName:\n                                    description: 'Container name: required for volumes, optional for env vars'\n                                    type: string\n                                  divisor:\n                                    anyOf:\n                                    - type: integer\n                                    - type: string\n                                    description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                    x-kubernetes-int-or-string: true\n                                  resource:\n                                    description: 'Required: resource to select'\n                                    type: string\n                                required:\n                                - resource\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            required:\n                            - path\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    emptyDir:\n                      description: |-\n                        emptyDir represents a temporary directory that shares a pod's lifetime.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                      properties:\n                        medium:\n                          description: |-\n                            medium represents what type of storage medium should back this directory.\n                            The default is \"\" which means to use the node's default medium.\n                            Must be an empty string (default) or Memory.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                          type: string\n                        sizeLimit:\n                          anyOf:\n                          - type: integer\n                          - type: string\n                          description: |-\n                            sizeLimit is the total amount of local storage required for this EmptyDir volume.\n                            The size limit is also applicable for memory medium.\n                            The maximum usage on memory medium EmptyDir would be the minimum value between\n                            the SizeLimit specified here and the sum of memory limits of all containers in a pod.\n                            The default is nil which means that the limit is undefined.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                          pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                          x-kubernetes-int-or-string: true\n                      type: object\n                    ephemeral:\n                      description: |-\n                        ephemeral represents a volume that is handled by a cluster storage driver.\n                        The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts,\n                        and deleted when the pod is removed.\n\n                        Use this if:\n                        a) the volume is only needed while the pod runs,\n                        b) features of normal volumes like restoring from snapshot or capacity\n                           tracking are needed,\n                        c) the storage driver is specified through a storage class, and\n                        d) the storage driver supports dynamic volume provisioning through\n                           a PersistentVolumeClaim (see EphemeralVolumeSource for more\n                           information on the connection between this volume type\n                           and PersistentVolumeClaim).\n\n                        Use PersistentVolumeClaim or one of the vendor-specific\n                        APIs for volumes that persist for longer than the lifecycle\n                        of an individual pod.\n\n                        Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to\n                        be used that way - see the documentation of the driver for\n                        more information.\n\n                        A pod can use both types of ephemeral volumes and\n                        persistent volumes at the same time.\n                      properties:\n                        volumeClaimTemplate:\n                          description: |-\n                            Will be used to create a stand-alone PVC to provision the volume.\n                            The pod in which this EphemeralVolumeSource is embedded will be the\n                            owner of the PVC, i.e. the PVC will be deleted together with the\n                            pod.  The name of the PVC will be `<pod name>-<volume name>` where\n                            `<volume name>` is the name from the `PodSpec.Volumes` array\n                            entry. Pod validation will reject the pod if the concatenated name\n                            is not valid for a PVC (for example, too long).\n\n                            An existing PVC with that name that is not owned by the pod\n                            will *not* be used for the pod to avoid using an unrelated\n                            volume by mistake. Starting the pod is then blocked until\n                            the unrelated PVC is removed. If such a pre-created PVC is\n                            meant to be used by the pod, the PVC has to updated with an\n                            owner reference to the pod once the pod exists. Normally\n                            this should not be necessary, but it may be useful when\n                            manually reconstructing a broken cluster.\n\n                            This field is read-only and no changes will be made by Kubernetes\n                            to the PVC after it has been created.\n\n                            Required, must not be nil.\n                          properties:\n                            metadata:\n                              description: |-\n                                May contain labels and annotations that will be copied into the PVC\n                                when creating it. No other fields are allowed and will be rejected during\n                                validation.\n                              type: object\n                            spec:\n                              description: |-\n                                The specification for the PersistentVolumeClaim. The entire content is\n                                copied unchanged into the PVC that gets created from this\n                                template. The same fields as in a PersistentVolumeClaim\n                                are also valid here.\n                              properties:\n                                accessModes:\n                                  description: |-\n                                    accessModes contains the desired access modes the volume should have.\n                                    More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                dataSource:\n                                  description: |-\n                                    dataSource field can be used to specify either:\n                                    * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n                                    * An existing PVC (PersistentVolumeClaim)\n                                    If the provisioner or an external controller can support the specified data source,\n                                    it will create a new volume based on the contents of the specified data source.\n                                    When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\n                                    and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\n                                    If the namespace is specified, then dataSourceRef will not be copied to dataSource.\n                                  properties:\n                                    apiGroup:\n                                      description: |-\n                                        APIGroup is the group for the resource being referenced.\n                                        If APIGroup is not specified, the specified Kind must be in the core API group.\n                                        For any other third-party types, APIGroup is required.\n                                      type: string\n                                    kind:\n                                      description: Kind is the type of resource being referenced\n                                      type: string\n                                    name:\n                                      description: Name is the name of resource being referenced\n                                      type: string\n                                  required:\n                                  - kind\n                                  - name\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                dataSourceRef:\n                                  description: |-\n                                    dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\n                                    volume is desired. This may be any object from a non-empty API group (non\n                                    core object) or a PersistentVolumeClaim object.\n                                    When this field is specified, volume binding will only succeed if the type of\n                                    the specified object matches some installed volume populator or dynamic\n                                    provisioner.\n                                    This field will replace the functionality of the dataSource field and as such\n                                    if both fields are non-empty, they must have the same value. For backwards\n                                    compatibility, when namespace isn't specified in dataSourceRef,\n                                    both fields (dataSource and dataSourceRef) will be set to the same\n                                    value automatically if one of them is empty and the other is non-empty.\n                                    When namespace is specified in dataSourceRef,\n                                    dataSource isn't set to the same value and must be empty.\n                                    There are three important differences between dataSource and dataSourceRef:\n                                    * While dataSource only allows two specific types of objects, dataSourceRef\n                                      allows any non-core object, as well as PersistentVolumeClaim objects.\n                                    * While dataSource ignores disallowed values (dropping them), dataSourceRef\n                                      preserves all values, and generates an error if a disallowed value is\n                                      specified.\n                                    * While dataSource only allows local objects, dataSourceRef allows objects\n                                      in any namespaces.\n                                    (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n                                    (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                  properties:\n                                    apiGroup:\n                                      description: |-\n                                        APIGroup is the group for the resource being referenced.\n                                        If APIGroup is not specified, the specified Kind must be in the core API group.\n                                        For any other third-party types, APIGroup is required.\n                                      type: string\n                                    kind:\n                                      description: Kind is the type of resource being referenced\n                                      type: string\n                                    name:\n                                      description: Name is the name of resource being referenced\n                                      type: string\n                                    namespace:\n                                      description: |-\n                                        Namespace is the namespace of resource being referenced\n                                        Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n                                        (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                      type: string\n                                  required:\n                                  - kind\n                                  - name\n                                  type: object\n                                resources:\n                                  description: |-\n                                    resources represents the minimum resources the volume should have.\n                                    If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\n                                    that are lower than previous value but must still be higher than capacity recorded in the\n                                    status field of the claim.\n                                    More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources\n                                  properties:\n                                    limits:\n                                      additionalProperties:\n                                        anyOf:\n                                        - type: integer\n                                        - type: string\n                                        pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                        x-kubernetes-int-or-string: true\n                                      description: |-\n                                        Limits describes the maximum amount of compute resources allowed.\n                                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                      type: object\n                                    requests:\n                                      additionalProperties:\n                                        anyOf:\n                                        - type: integer\n                                        - type: string\n                                        pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                        x-kubernetes-int-or-string: true\n                                      description: |-\n                                        Requests describes the minimum amount of compute resources required.\n                                        If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                                        otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                      type: object\n                                  type: object\n                                selector:\n                                  description: selector is a label query over volumes to consider for binding.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                storageClassName:\n                                  description: |-\n                                    storageClassName is the name of the StorageClass required by the claim.\n                                    More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1\n                                  type: string\n                                volumeAttributesClassName:\n                                  description: |-\n                                    volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\n                                    If specified, the CSI driver will create or update the volume with the attributes defined\n                                    in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\n                                    it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\n                                    will be applied to the claim but it's not allowed to reset this field to empty string once it is set.\n                                    If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\n                                    will be set by the persistentvolume controller if it exists.\n                                    If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\n                                    set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\n                                    exists.\n                                    More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n                                    (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).\n                                  type: string\n                                volumeMode:\n                                  description: |-\n                                    volumeMode defines what type of volume is required by the claim.\n                                    Value of Filesystem is implied when not included in claim spec.\n                                  type: string\n                                volumeName:\n                                  description: volumeName is the binding reference to the PersistentVolume backing this claim.\n                                  type: string\n                              type: object\n                          required:\n                          - spec\n                          type: object\n                      type: object\n                    fc:\n                      description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        lun:\n                          description: 'lun is Optional: FC target lun number'\n                          format: int32\n                          type: integer\n                        readOnly:\n                          description: |-\n                            readOnly is Optional: Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        targetWWNs:\n                          description: 'targetWWNs is Optional: FC target worldwide names (WWNs)'\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        wwids:\n                          description: |-\n                            wwids Optional: FC volume world wide identifiers (wwids)\n                            Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    flexVolume:\n                      description: |-\n                        flexVolume represents a generic volume resource that is\n                        provisioned/attached using an exec based plugin.\n                        Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead.\n                      properties:\n                        driver:\n                          description: driver is the name of the driver to use for this volume.\n                          type: string\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". The default filesystem depends on FlexVolume script.\n                          type: string\n                        options:\n                          additionalProperties:\n                            type: string\n                          description: 'options is Optional: this field holds extra command options if any.'\n                          type: object\n                        readOnly:\n                          description: |-\n                            readOnly is Optional: defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef is Optional: secretRef is reference to the secret object containing\n                            sensitive information to pass to the plugin scripts. This may be\n                            empty if no secret object is specified. If the secret object\n                            contains more than one secret, all secrets are passed to the plugin\n                            scripts.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      required:\n                      - driver\n                      type: object\n                    flocker:\n                      description: |-\n                        flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running.\n                        Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported.\n                      properties:\n                        datasetName:\n                          description: |-\n                            datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker\n                            should be considered as deprecated\n                          type: string\n                        datasetUUID:\n                          description: datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset\n                          type: string\n                      type: object\n                    gcePersistentDisk:\n                      description: |-\n                        gcePersistentDisk represents a GCE Disk resource that is attached to a\n                        kubelet's host machine and then exposed to the pod.\n                        Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree\n                        gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          type: string\n                        partition:\n                          description: |-\n                            partition is the partition in the volume that you want to mount.\n                            If omitted, the default is to mount by volume name.\n                            Examples: For volume /dev/sda1, you specify the partition as \"1\".\n                            Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty).\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          format: int32\n                          type: integer\n                        pdName:\n                          description: |-\n                            pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the ReadOnly setting in VolumeMounts.\n                            Defaults to false.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          type: boolean\n                      required:\n                      - pdName\n                      type: object\n                    gitRepo:\n                      description: |-\n                        gitRepo represents a git repository at a particular revision.\n                        Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an\n                        EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir\n                        into the Pod's container.\n                      properties:\n                        directory:\n                          description: |-\n                            directory is the target directory name.\n                            Must not contain or start with '..'.  If '.' is supplied, the volume directory will be the\n                            git repository.  Otherwise, if specified, the volume will contain the git repository in\n                            the subdirectory with the given name.\n                          type: string\n                        repository:\n                          description: repository is the URL\n                          type: string\n                        revision:\n                          description: revision is the commit hash for the specified revision.\n                          type: string\n                      required:\n                      - repository\n                      type: object\n                    glusterfs:\n                      description: |-\n                        glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime.\n                        Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported.\n                        More info: https://examples.k8s.io/volumes/glusterfs/README.md\n                      properties:\n                        endpoints:\n                          description: |-\n                            endpoints is the endpoint name that details Glusterfs topology.\n                            More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod\n                          type: string\n                        path:\n                          description: |-\n                            path is the Glusterfs volume path.\n                            More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the Glusterfs volume to be mounted with read-only permissions.\n                            Defaults to false.\n                            More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod\n                          type: boolean\n                      required:\n                      - endpoints\n                      - path\n                      type: object\n                    hostPath:\n                      description: |-\n                        hostPath represents a pre-existing file or directory on the host\n                        machine that is directly exposed to the container. This is generally\n                        used for system agents or other privileged things that are allowed\n                        to see the host machine. Most containers will NOT need this.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath\n                      properties:\n                        path:\n                          description: |-\n                            path of the directory on the host.\n                            If the path is a symlink, it will follow the link to the real path.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath\n                          type: string\n                        type:\n                          description: |-\n                            type for HostPath Volume\n                            Defaults to \"\"\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath\n                          type: string\n                      required:\n                      - path\n                      type: object\n                    image:\n                      description: |-\n                        image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine.\n                        The volume is resolved at pod startup depending on which PullPolicy value is provided:\n\n                        - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails.\n                        - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.\n                        - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n\n                        The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation.\n                        A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message.\n                        The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field.\n                        The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images.\n                        The volume will be mounted read-only (ro) and non-executable files (noexec).\n                        Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33.\n                        The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.\n                      properties:\n                        pullPolicy:\n                          description: |-\n                            Policy for pulling OCI objects. Possible values are:\n                            Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails.\n                            Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.\n                            IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n                            Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.\n                          type: string\n                        reference:\n                          description: |-\n                            Required: Image or artifact reference to be used.\n                            Behaves in the same way as pod.spec.containers[*].image.\n                            Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets.\n                            More info: https://kubernetes.io/docs/concepts/containers/images\n                            This field is optional to allow higher level config management to default or override\n                            container images in workload controllers like Deployments and StatefulSets.\n                          type: string\n                      type: object\n                    iscsi:\n                      description: |-\n                        iscsi represents an ISCSI Disk resource that is attached to a\n                        kubelet's host machine and then exposed to the pod.\n                        More info: https://examples.k8s.io/volumes/iscsi/README.md\n                      properties:\n                        chapAuthDiscovery:\n                          description: chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication\n                          type: boolean\n                        chapAuthSession:\n                          description: chapAuthSession defines whether support iSCSI Session CHAP authentication\n                          type: boolean\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi\n                          type: string\n                        initiatorName:\n                          description: |-\n                            initiatorName is the custom iSCSI Initiator Name.\n                            If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface\n                            <target portal>:<volume name> will be created for the connection.\n                          type: string\n                        iqn:\n                          description: iqn is the target iSCSI Qualified Name.\n                          type: string\n                        iscsiInterface:\n                          default: default\n                          description: |-\n                            iscsiInterface is the interface Name that uses an iSCSI transport.\n                            Defaults to 'default' (tcp).\n                          type: string\n                        lun:\n                          description: lun represents iSCSI Target Lun number.\n                          format: int32\n                          type: integer\n                        portals:\n                          description: |-\n                            portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port\n                            is other than default (typically TCP ports 860 and 3260).\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        readOnly:\n                          description: |-\n                            readOnly here will force the ReadOnly setting in VolumeMounts.\n                            Defaults to false.\n                          type: boolean\n                        secretRef:\n                          description: secretRef is the CHAP Secret for iSCSI target and initiator authentication\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        targetPortal:\n                          description: |-\n                            targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port\n                            is other than default (typically TCP ports 860 and 3260).\n                          type: string\n                      required:\n                      - iqn\n                      - lun\n                      - targetPortal\n                      type: object\n                    name:\n                      description: |-\n                        name of the volume.\n                        Must be a DNS_LABEL and unique within the pod.\n                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                      type: string\n                    nfs:\n                      description: |-\n                        nfs represents an NFS mount on the host that shares a pod's lifetime\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                      properties:\n                        path:\n                          description: |-\n                            path that is exported by the NFS server.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the NFS export to be mounted with read-only permissions.\n                            Defaults to false.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                          type: boolean\n                        server:\n                          description: |-\n                            server is the hostname or IP address of the NFS server.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                          type: string\n                      required:\n                      - path\n                      - server\n                      type: object\n                    persistentVolumeClaim:\n                      description: |-\n                        persistentVolumeClaimVolumeSource represents a reference to a\n                        PersistentVolumeClaim in the same namespace.\n                        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims\n                      properties:\n                        claimName:\n                          description: |-\n                            claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume.\n                            More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly Will force the ReadOnly setting in VolumeMounts.\n                            Default false.\n                          type: boolean\n                      required:\n                      - claimName\n                      type: object\n                    photonPersistentDisk:\n                      description: |-\n                        photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine.\n                        Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        pdID:\n                          description: pdID is the ID that identifies Photon Controller persistent disk\n                          type: string\n                      required:\n                      - pdID\n                      type: object\n                    portworxVolume:\n                      description: |-\n                        portworxVolume represents a portworx volume attached and mounted on kubelets host machine.\n                        Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type\n                        are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate\n                        is on.\n                      properties:\n                        fsType:\n                          description: |-\n                            fSType represents the filesystem type to mount\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        volumeID:\n                          description: volumeID uniquely identifies a Portworx volume\n                          type: string\n                      required:\n                      - volumeID\n                      type: object\n                    projected:\n                      description: projected items for all in one resources secrets, configmaps, and downward API\n                      properties:\n                        defaultMode:\n                          description: |-\n                            defaultMode are the mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        sources:\n                          description: |-\n                            sources is the list of volume projections. Each entry in this list\n                            handles one source.\n                          items:\n                            description: |-\n                              Projection that may be projected along with other supported volume types.\n                              Exactly one of these fields must be set.\n                            properties:\n                              clusterTrustBundle:\n                                description: |-\n                                  ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field\n                                  of ClusterTrustBundle objects in an auto-updating file.\n\n                                  Alpha, gated by the ClusterTrustBundleProjection feature gate.\n\n                                  ClusterTrustBundle objects can either be selected by name, or by the\n                                  combination of signer name and a label selector.\n\n                                  Kubelet performs aggressive normalization of the PEM contents written\n                                  into the pod filesystem.  Esoteric PEM features such as inter-block\n                                  comments and block headers are stripped.  Certificates are deduplicated.\n                                  The ordering of certificates within the file is arbitrary, and Kubelet\n                                  may change the order over time.\n                                properties:\n                                  labelSelector:\n                                    description: |-\n                                      Select all ClusterTrustBundles that match this label selector.  Only has\n                                      effect if signerName is set.  Mutually-exclusive with name.  If unset,\n                                      interpreted as \"match nothing\".  If set but empty, interpreted as \"match\n                                      everything\".\n                                    properties:\n                                      matchExpressions:\n                                        description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                        items:\n                                          description: |-\n                                            A label selector requirement is a selector that contains values, a key, and an operator that\n                                            relates the key and values.\n                                          properties:\n                                            key:\n                                              description: key is the label key that the selector applies to.\n                                              type: string\n                                            operator:\n                                              description: |-\n                                                operator represents a key's relationship to a set of values.\n                                                Valid operators are In, NotIn, Exists and DoesNotExist.\n                                              type: string\n                                            values:\n                                              description: |-\n                                                values is an array of string values. If the operator is In or NotIn,\n                                                the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                                the values array must be empty. This array is replaced during a strategic\n                                                merge patch.\n                                              items:\n                                                type: string\n                                              type: array\n                                              x-kubernetes-list-type: atomic\n                                          required:\n                                          - key\n                                          - operator\n                                          type: object\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                      matchLabels:\n                                        additionalProperties:\n                                          type: string\n                                        description: |-\n                                          matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                          map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                          operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                        type: object\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  name:\n                                    description: |-\n                                      Select a single ClusterTrustBundle by object name.  Mutually-exclusive\n                                      with signerName and labelSelector.\n                                    type: string\n                                  optional:\n                                    description: |-\n                                      If true, don't block pod startup if the referenced ClusterTrustBundle(s)\n                                      aren't available.  If using name, then the named ClusterTrustBundle is\n                                      allowed not to exist.  If using signerName, then the combination of\n                                      signerName and labelSelector is allowed to match zero\n                                      ClusterTrustBundles.\n                                    type: boolean\n                                  path:\n                                    description: Relative path from the volume root to write the bundle.\n                                    type: string\n                                  signerName:\n                                    description: |-\n                                      Select all ClusterTrustBundles that match this signer name.\n                                      Mutually-exclusive with name.  The contents of all selected\n                                      ClusterTrustBundles will be unified and deduplicated.\n                                    type: string\n                                required:\n                                - path\n                                type: object\n                              configMap:\n                                description: configMap information about the configMap data to project\n                                properties:\n                                  items:\n                                    description: |-\n                                      items if unspecified, each key-value pair in the Data field of the referenced\n                                      ConfigMap will be projected into the volume as a file whose name is the\n                                      key and content is the value. If specified, the listed keys will be\n                                      projected into the specified paths, and unlisted keys will not be\n                                      present. If a key is specified which is not present in the ConfigMap,\n                                      the volume setup will error unless it is marked optional. Paths must be\n                                      relative and may not contain the '..' path or start with '..'.\n                                    items:\n                                      description: Maps a string key to a path within a volume.\n                                      properties:\n                                        key:\n                                          description: key is the key to project.\n                                          type: string\n                                        mode:\n                                          description: |-\n                                            mode is Optional: mode bits used to set permissions on this file.\n                                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                            If not specified, the volume defaultMode will be used.\n                                            This might be in conflict with other options that affect the file\n                                            mode, like fsGroup, and the result can be other mode bits set.\n                                          format: int32\n                                          type: integer\n                                        path:\n                                          description: |-\n                                            path is the relative path of the file to map the key to.\n                                            May not be an absolute path.\n                                            May not contain the path element '..'.\n                                            May not start with the string '..'.\n                                          type: string\n                                      required:\n                                      - key\n                                      - path\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: optional specify whether the ConfigMap or its keys must be defined\n                                    type: boolean\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              downwardAPI:\n                                description: downwardAPI information about the downwardAPI data to project\n                                properties:\n                                  items:\n                                    description: Items is a list of DownwardAPIVolume file\n                                    items:\n                                      description: DownwardAPIVolumeFile represents information to create the file containing the pod field\n                                      properties:\n                                        fieldRef:\n                                          description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.'\n                                          properties:\n                                            apiVersion:\n                                              description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                              type: string\n                                            fieldPath:\n                                              description: Path of the field to select in the specified API version.\n                                              type: string\n                                          required:\n                                          - fieldPath\n                                          type: object\n                                          x-kubernetes-map-type: atomic\n                                        mode:\n                                          description: |-\n                                            Optional: mode bits used to set permissions on this file, must be an octal value\n                                            between 0000 and 0777 or a decimal value between 0 and 511.\n                                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                            If not specified, the volume defaultMode will be used.\n                                            This might be in conflict with other options that affect the file\n                                            mode, like fsGroup, and the result can be other mode bits set.\n                                          format: int32\n                                          type: integer\n                                        path:\n                                          description: 'Required: Path is  the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..'''\n                                          type: string\n                                        resourceFieldRef:\n                                          description: |-\n                                            Selects a resource of the container: only resources limits and requests\n                                            (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.\n                                          properties:\n                                            containerName:\n                                              description: 'Container name: required for volumes, optional for env vars'\n                                              type: string\n                                            divisor:\n                                              anyOf:\n                                              - type: integer\n                                              - type: string\n                                              description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                              pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                              x-kubernetes-int-or-string: true\n                                            resource:\n                                              description: 'Required: resource to select'\n                                              type: string\n                                          required:\n                                          - resource\n                                          type: object\n                                          x-kubernetes-map-type: atomic\n                                      required:\n                                      - path\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                type: object\n                              secret:\n                                description: secret information about the secret data to project\n                                properties:\n                                  items:\n                                    description: |-\n                                      items if unspecified, each key-value pair in the Data field of the referenced\n                                      Secret will be projected into the volume as a file whose name is the\n                                      key and content is the value. If specified, the listed keys will be\n                                      projected into the specified paths, and unlisted keys will not be\n                                      present. If a key is specified which is not present in the Secret,\n                                      the volume setup will error unless it is marked optional. Paths must be\n                                      relative and may not contain the '..' path or start with '..'.\n                                    items:\n                                      description: Maps a string key to a path within a volume.\n                                      properties:\n                                        key:\n                                          description: key is the key to project.\n                                          type: string\n                                        mode:\n                                          description: |-\n                                            mode is Optional: mode bits used to set permissions on this file.\n                                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                            If not specified, the volume defaultMode will be used.\n                                            This might be in conflict with other options that affect the file\n                                            mode, like fsGroup, and the result can be other mode bits set.\n                                          format: int32\n                                          type: integer\n                                        path:\n                                          description: |-\n                                            path is the relative path of the file to map the key to.\n                                            May not be an absolute path.\n                                            May not contain the path element '..'.\n                                            May not start with the string '..'.\n                                          type: string\n                                      required:\n                                      - key\n                                      - path\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: optional field specify whether the Secret or its key must be defined\n                                    type: boolean\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              serviceAccountToken:\n                                description: serviceAccountToken is information about the serviceAccountToken data to project\n                                properties:\n                                  audience:\n                                    description: |-\n                                      audience is the intended audience of the token. A recipient of a token\n                                      must identify itself with an identifier specified in the audience of the\n                                      token, and otherwise should reject the token. The audience defaults to the\n                                      identifier of the apiserver.\n                                    type: string\n                                  expirationSeconds:\n                                    description: |-\n                                      expirationSeconds is the requested duration of validity of the service\n                                      account token. As the token approaches expiration, the kubelet volume\n                                      plugin will proactively rotate the service account token. The kubelet will\n                                      start trying to rotate the token if the token is older than 80 percent of\n                                      its time to live or if the token is older than 24 hours.Defaults to 1 hour\n                                      and must be at least 10 minutes.\n                                    format: int64\n                                    type: integer\n                                  path:\n                                    description: |-\n                                      path is the path relative to the mount point of the file to project the\n                                      token into.\n                                    type: string\n                                required:\n                                - path\n                                type: object\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    quobyte:\n                      description: |-\n                        quobyte represents a Quobyte mount on the host that shares a pod's lifetime.\n                        Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported.\n                      properties:\n                        group:\n                          description: |-\n                            group to map volume access to\n                            Default is no group\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the Quobyte volume to be mounted with read-only permissions.\n                            Defaults to false.\n                          type: boolean\n                        registry:\n                          description: |-\n                            registry represents a single or multiple Quobyte Registry services\n                            specified as a string as host:port pair (multiple entries are separated with commas)\n                            which acts as the central registry for volumes\n                          type: string\n                        tenant:\n                          description: |-\n                            tenant owning the given Quobyte volume in the Backend\n                            Used with dynamically provisioned Quobyte volumes, value is set by the plugin\n                          type: string\n                        user:\n                          description: |-\n                            user to map volume access to\n                            Defaults to serivceaccount user\n                          type: string\n                        volume:\n                          description: volume is a string that references an already created Quobyte volume by name.\n                          type: string\n                      required:\n                      - registry\n                      - volume\n                      type: object\n                    rbd:\n                      description: |-\n                        rbd represents a Rados Block Device mount on the host that shares a pod's lifetime.\n                        Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported.\n                        More info: https://examples.k8s.io/volumes/rbd/README.md\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd\n                          type: string\n                        image:\n                          description: |-\n                            image is the rados image name.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                        keyring:\n                          default: /etc/ceph/keyring\n                          description: |-\n                            keyring is the path to key ring for RBDUser.\n                            Default is /etc/ceph/keyring.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                        monitors:\n                          description: |-\n                            monitors is a collection of Ceph monitors.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        pool:\n                          default: rbd\n                          description: |-\n                            pool is the rados pool name.\n                            Default is rbd.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the ReadOnly setting in VolumeMounts.\n                            Defaults to false.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef is name of the authentication secret for RBDUser. If provided\n                            overrides keyring.\n                            Default is nil.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        user:\n                          default: admin\n                          description: |-\n                            user is the rados user name.\n                            Default is admin.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                      required:\n                      - image\n                      - monitors\n                      type: object\n                    scaleIO:\n                      description: |-\n                        scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.\n                        Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported.\n                      properties:\n                        fsType:\n                          default: xfs\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\".\n                            Default is \"xfs\".\n                          type: string\n                        gateway:\n                          description: gateway is the host address of the ScaleIO API Gateway.\n                          type: string\n                        protectionDomain:\n                          description: protectionDomain is the name of the ScaleIO Protection Domain for the configured storage.\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef references to the secret for ScaleIO user and other\n                            sensitive information. If this is not provided, Login operation will fail.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        sslEnabled:\n                          description: sslEnabled Flag enable/disable SSL communication with Gateway, default false\n                          type: boolean\n                        storageMode:\n                          default: ThinProvisioned\n                          description: |-\n                            storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.\n                            Default is ThinProvisioned.\n                          type: string\n                        storagePool:\n                          description: storagePool is the ScaleIO Storage Pool associated with the protection domain.\n                          type: string\n                        system:\n                          description: system is the name of the storage system as configured in ScaleIO.\n                          type: string\n                        volumeName:\n                          description: |-\n                            volumeName is the name of a volume already created in the ScaleIO system\n                            that is associated with this volume source.\n                          type: string\n                      required:\n                      - gateway\n                      - secretRef\n                      - system\n                      type: object\n                    secret:\n                      description: |-\n                        secret represents a secret that should populate this volume.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#secret\n                      properties:\n                        defaultMode:\n                          description: |-\n                            defaultMode is Optional: mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values\n                            for mode bits. Defaults to 0644.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        items:\n                          description: |-\n                            items If unspecified, each key-value pair in the Data field of the referenced\n                            Secret will be projected into the volume as a file whose name is the\n                            key and content is the value. If specified, the listed keys will be\n                            projected into the specified paths, and unlisted keys will not be\n                            present. If a key is specified which is not present in the Secret,\n                            the volume setup will error unless it is marked optional. Paths must be\n                            relative and may not contain the '..' path or start with '..'.\n                          items:\n                            description: Maps a string key to a path within a volume.\n                            properties:\n                              key:\n                                description: key is the key to project.\n                                type: string\n                              mode:\n                                description: |-\n                                  mode is Optional: mode bits used to set permissions on this file.\n                                  Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                  YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                  If not specified, the volume defaultMode will be used.\n                                  This might be in conflict with other options that affect the file\n                                  mode, like fsGroup, and the result can be other mode bits set.\n                                format: int32\n                                type: integer\n                              path:\n                                description: |-\n                                  path is the relative path of the file to map the key to.\n                                  May not be an absolute path.\n                                  May not contain the path element '..'.\n                                  May not start with the string '..'.\n                                type: string\n                            required:\n                            - key\n                            - path\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        optional:\n                          description: optional field specify whether the Secret or its keys must be defined\n                          type: boolean\n                        secretName:\n                          description: |-\n                            secretName is the name of the secret in the pod's namespace to use.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#secret\n                          type: string\n                      type: object\n                    storageos:\n                      description: |-\n                        storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes.\n                        Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef specifies the secret to use for obtaining the StorageOS API\n                            credentials.  If not specified, default values will be attempted.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        volumeName:\n                          description: |-\n                            volumeName is the human-readable name of the StorageOS volume.  Volume\n                            names are only unique within a namespace.\n                          type: string\n                        volumeNamespace:\n                          description: |-\n                            volumeNamespace specifies the scope of the volume within StorageOS.  If no\n                            namespace is specified then the Pod's namespace will be used.  This allows the\n                            Kubernetes name scoping to be mirrored within StorageOS for tighter integration.\n                            Set VolumeName to any name to override the default behaviour.\n                            Set to \"default\" if you are not using namespaces within StorageOS.\n                            Namespaces that do not pre-exist within StorageOS will be created.\n                          type: string\n                      type: object\n                    vsphereVolume:\n                      description: |-\n                        vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine.\n                        Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type\n                        are redirected to the csi.vsphere.vmware.com CSI driver.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        storagePolicyID:\n                          description: storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName.\n                          type: string\n                        storagePolicyName:\n                          description: storagePolicyName is the storage Policy Based Management (SPBM) profile name.\n                          type: string\n                        volumePath:\n                          description: volumePath is the path that identifies vSphere volume vmdk\n                          type: string\n                      required:\n                      - volumePath\n                      type: object\n                  required:\n                  - name\n                  type: object\n                type: array\n              walCompression:\n                description: |-\n                  Configures compression of the write-ahead log (WAL) using Snappy.\n\n                  WAL compression is enabled by default for Prometheus >= 2.20.0\n\n                  Requires Prometheus v2.11.0 and above.\n                type: boolean\n              web:\n                description: Defines the configuration of the Prometheus web server.\n                properties:\n                  httpConfig:\n                    description: Defines HTTP parameters for web server.\n                    properties:\n                      headers:\n                        description: List of headers that can be added to HTTP responses.\n                        properties:\n                          contentSecurityPolicy:\n                            description: |-\n                              Set the Content-Security-Policy header to HTTP responses.\n                              Unset if blank.\n                            type: string\n                          strictTransportSecurity:\n                            description: |-\n                              Set the Strict-Transport-Security header to HTTP responses.\n                              Unset if blank.\n                              Please make sure that you use this with care as this header might force\n                              browsers to load Prometheus and the other applications hosted on the same\n                              domain and subdomains over HTTPS.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security\n                            type: string\n                          xContentTypeOptions:\n                            description: |-\n                              Set the X-Content-Type-Options header to HTTP responses.\n                              Unset if blank. Accepted value is nosniff.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n                            enum:\n                            - \"\"\n                            - NoSniff\n                            type: string\n                          xFrameOptions:\n                            description: |-\n                              Set the X-Frame-Options header to HTTP responses.\n                              Unset if blank. Accepted values are deny and sameorigin.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n                            enum:\n                            - \"\"\n                            - Deny\n                            - SameOrigin\n                            type: string\n                          xXSSProtection:\n                            description: |-\n                              Set the X-XSS-Protection header to all responses.\n                              Unset if blank.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n                            type: string\n                        type: object\n                      http2:\n                        description: |-\n                          Enable HTTP/2 support. Note that HTTP/2 is only supported with TLS.\n                          When TLSConfig is not configured, HTTP/2 will be disabled.\n                          Whenever the value of the field changes, a rolling update will be triggered.\n                        type: boolean\n                    type: object\n                  maxConnections:\n                    description: |-\n                      Defines the maximum number of simultaneous connections\n                      A zero value means that Prometheus doesn't accept any incoming connection.\n                    format: int32\n                    minimum: 0\n                    type: integer\n                  pageTitle:\n                    description: The prometheus web page title.\n                    type: string\n                  tlsConfig:\n                    description: Defines the TLS parameters for HTTPS.\n                    properties:\n                      cert:\n                        description: |-\n                          Secret or ConfigMap containing the TLS certificate for the web server.\n\n                          Either `keySecret` or `keyFile` must be defined.\n\n                          It is mutually exclusive with `certFile`.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      certFile:\n                        description: |-\n                          Path to the TLS certificate file in the container for the web server.\n\n                          Either `keySecret` or `keyFile` must be defined.\n\n                          It is mutually exclusive with `cert`.\n                        type: string\n                      cipherSuites:\n                        description: |-\n                          List of supported cipher suites for TLS versions up to TLS 1.2.\n\n                          If not defined, the Go default cipher suites are used.\n                          Available cipher suites are documented in the Go documentation:\n                          https://golang.org/pkg/crypto/tls/#pkg-constants\n                        items:\n                          type: string\n                        type: array\n                      client_ca:\n                        description: |-\n                          Secret or ConfigMap containing the CA certificate for client certificate\n                          authentication to the server.\n\n                          It is mutually exclusive with `clientCAFile`.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      clientAuthType:\n                        description: |-\n                          The server policy for client TLS authentication.\n\n                          For more detail on clientAuth options:\n                          https://golang.org/pkg/crypto/tls/#ClientAuthType\n                        type: string\n                      clientCAFile:\n                        description: |-\n                          Path to the CA certificate file for client certificate authentication to\n                          the server.\n\n                          It is mutually exclusive with `client_ca`.\n                        type: string\n                      curvePreferences:\n                        description: |-\n                          Elliptic curves that will be used in an ECDHE handshake, in preference\n                          order.\n\n                          Available curves are documented in the Go documentation:\n                          https://golang.org/pkg/crypto/tls/#CurveID\n                        items:\n                          type: string\n                        type: array\n                      keyFile:\n                        description: |-\n                          Path to the TLS private key file in the container for the web server.\n\n                          If defined, either `cert` or `certFile` must be defined.\n\n                          It is mutually exclusive with `keySecret`.\n                        type: string\n                      keySecret:\n                        description: |-\n                          Secret containing the TLS private key for the web server.\n\n                          Either `cert` or `certFile` must be defined.\n\n                          It is mutually exclusive with `keyFile`.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: Maximum TLS version that is acceptable.\n                        type: string\n                      minVersion:\n                        description: Minimum TLS version that is acceptable.\n                        type: string\n                      preferServerCipherSuites:\n                        description: |-\n                          Controls whether the server selects the client's most preferred cipher\n                          suite, or the server's most preferred cipher suite.\n\n                          If true then the server's preference, as expressed in\n                          the order of elements in cipherSuites, is used.\n                        type: boolean\n                    type: object\n                type: object\n            type: object\n          status:\n            description: |-\n              Most recent observed status of the Prometheus cluster. Read-only.\n              More info:\n              https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n            properties:\n              availableReplicas:\n                description: |-\n                  Total number of available pods (ready for at least minReadySeconds)\n                  targeted by this Prometheus deployment.\n                format: int32\n                type: integer\n              conditions:\n                description: The current state of the Prometheus deployment.\n                items:\n                  description: |-\n                    Condition represents the state of the resources associated with the\n                    Prometheus, Alertmanager or ThanosRuler resource.\n                  properties:\n                    lastTransitionTime:\n                      description: lastTransitionTime is the time of the last update to the current status property.\n                      format: date-time\n                      type: string\n                    message:\n                      description: Human-readable message indicating details for the condition's last transition.\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        ObservedGeneration represents the .metadata.generation that the\n                        condition was set based upon. For instance, if `.metadata.generation` is\n                        currently 12, but the `.status.conditions[].observedGeneration` is 9, the\n                        condition is out of date with respect to the current state of the\n                        instance.\n                      format: int64\n                      type: integer\n                    reason:\n                      description: Reason for the condition's last transition.\n                      type: string\n                    status:\n                      description: Status of the condition.\n                      minLength: 1\n                      type: string\n                    type:\n                      description: Type of the condition being reported.\n                      minLength: 1\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - status\n                  - type\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              paused:\n                description: |-\n                  Represents whether any actions on the underlying managed objects are\n                  being performed. Only delete actions will be performed.\n                type: boolean\n              replicas:\n                description: |-\n                  Total number of non-terminated pods targeted by this Prometheus deployment\n                  (their labels match the selector).\n                format: int32\n                type: integer\n              selector:\n                description: The selector used to match the pods targeted by this Prometheus resource.\n                type: string\n              shardStatuses:\n                description: The list has one entry per shard. Each entry provides a summary of the shard status.\n                items:\n                  properties:\n                    availableReplicas:\n                      description: |-\n                        Total number of available pods (ready for at least minReadySeconds)\n                        targeted by this shard.\n                      format: int32\n                      type: integer\n                    replicas:\n                      description: Total number of pods targeted by this shard.\n                      format: int32\n                      type: integer\n                    shardID:\n                      description: Identifier of the shard.\n                      type: string\n                    unavailableReplicas:\n                      description: Total number of unavailable pods targeted by this shard.\n                      format: int32\n                      type: integer\n                    updatedReplicas:\n                      description: |-\n                        Total number of non-terminated pods targeted by this shard\n                        that have the desired spec.\n                      format: int32\n                      type: integer\n                  required:\n                  - availableReplicas\n                  - replicas\n                  - shardID\n                  - unavailableReplicas\n                  - updatedReplicas\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - shardID\n                x-kubernetes-list-type: map\n              shards:\n                description: Shards is the most recently observed number of shards.\n                format: int32\n                type: integer\n              unavailableReplicas:\n                description: Total number of unavailable pods targeted by this Prometheus deployment.\n                format: int32\n                type: integer\n              updatedReplicas:\n                description: |-\n                  Total number of non-terminated pods targeted by this Prometheus deployment\n                  that have the desired version spec.\n                format: int32\n                type: integer\n            required:\n            - availableReplicas\n            - paused\n            - replicas\n            - unavailableReplicas\n            - updatedReplicas\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      scale:\n        labelSelectorPath: .status.selector\n        specReplicasPath: .spec.shards\n        statusReplicasPath: .status.shards\n      status: {}\n"
  },
  {
    "path": "hack/config/monitoring/crds/0prometheusagentCustomResourceDefinition.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.18.0\n    operator.prometheus.io/version: 0.85.0\n  name: prometheusagents.monitoring.coreos.com\nspec:\n  group: monitoring.coreos.com\n  names:\n    categories:\n    - prometheus-operator\n    kind: PrometheusAgent\n    listKind: PrometheusAgentList\n    plural: prometheusagents\n    shortNames:\n    - promagent\n    singular: prometheusagent\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - description: The version of Prometheus agent\n      jsonPath: .spec.version\n      name: Version\n      type: string\n    - description: The number of desired replicas\n      jsonPath: .spec.replicas\n      name: Desired\n      type: integer\n    - description: The number of ready replicas\n      jsonPath: .status.availableReplicas\n      name: Ready\n      type: integer\n    - jsonPath: .status.conditions[?(@.type == 'Reconciled')].status\n      name: Reconciled\n      type: string\n    - jsonPath: .status.conditions[?(@.type == 'Available')].status\n      name: Available\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    - description: Whether the resource reconciliation is paused or not\n      jsonPath: .status.paused\n      name: Paused\n      priority: 1\n      type: boolean\n    name: v1alpha1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The `PrometheusAgent` custom resource definition (CRD) defines a desired [Prometheus Agent](https://prometheus.io/blog/2021/11/16/agent/) setup to run in a Kubernetes cluster.\n\n          The CRD is very similar to the `Prometheus` CRD except for features which aren't available in agent mode like rule evaluation, persistent storage and Thanos sidecar.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: |-\n              Specification of the desired behavior of the Prometheus agent. More info:\n              https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n            properties:\n              additionalArgs:\n                description: |-\n                  AdditionalArgs allows setting additional arguments for the 'prometheus' container.\n\n                  It is intended for e.g. activating hidden flags which are not supported by\n                  the dedicated configuration options yet. The arguments are passed as-is to the\n                  Prometheus container which may cause issues if they are invalid or not supported\n                  by the given Prometheus version.\n\n                  In case of an argument conflict (e.g. an argument which is already set by the\n                  operator itself) or when providing an invalid argument, the reconciliation will\n                  fail and an error will be logged.\n                items:\n                  description: Argument as part of the AdditionalArgs list.\n                  properties:\n                    name:\n                      description: Name of the argument, e.g. \"scrape.discovery-reload-interval\".\n                      minLength: 1\n                      type: string\n                    value:\n                      description: Argument value, e.g. 30s. Can be empty for name-only arguments (e.g. --storage.tsdb.no-lockfile)\n                      type: string\n                  required:\n                  - name\n                  type: object\n                type: array\n              additionalScrapeConfigs:\n                description: |-\n                  AdditionalScrapeConfigs allows specifying a key of a Secret containing\n                  additional Prometheus scrape configurations. Scrape configurations\n                  specified are appended to the configurations generated by the Prometheus\n                  Operator. Job configurations specified must have the form as specified\n                  in the official Prometheus documentation:\n                  https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config.\n                  As scrape configs are appended, the user is responsible to make sure it\n                  is valid. Note that using this feature may expose the possibility to\n                  break upgrades of Prometheus. It is advised to review Prometheus release\n                  notes to ensure that no incompatible scrape configs are going to break\n                  Prometheus after the upgrade.\n                properties:\n                  key:\n                    description: The key of the secret to select from.  Must be a valid secret key.\n                    type: string\n                  name:\n                    default: \"\"\n                    description: |-\n                      Name of the referent.\n                      This field is effectively required, but due to backwards compatibility is\n                      allowed to be empty. Instances of this type with an empty value here are\n                      almost certainly wrong.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                    type: string\n                  optional:\n                    description: Specify whether the Secret or its key must be defined\n                    type: boolean\n                required:\n                - key\n                type: object\n                x-kubernetes-map-type: atomic\n              affinity:\n                description: Defines the Pods' affinity scheduling rules if specified.\n                properties:\n                  nodeAffinity:\n                    description: Describes node affinity scheduling rules for the pod.\n                    properties:\n                      preferredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          The scheduler will prefer to schedule pods to nodes that satisfy\n                          the affinity expressions specified by this field, but it may choose\n                          a node that violates one or more of the expressions. The node that is\n                          most preferred is the one with the greatest sum of weights, i.e.\n                          for each node that meets all of the scheduling requirements (resource\n                          request, requiredDuringScheduling affinity expressions, etc.),\n                          compute a sum by iterating through the elements of this field and adding\n                          \"weight\" to the sum if the node matches the corresponding matchExpressions; the\n                          node(s) with the highest sum are the most preferred.\n                        items:\n                          description: |-\n                            An empty preferred scheduling term matches all objects with implicit weight 0\n                            (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).\n                          properties:\n                            preference:\n                              description: A node selector term, associated with the corresponding weight.\n                              properties:\n                                matchExpressions:\n                                  description: A list of node selector requirements by node's labels.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchFields:\n                                  description: A list of node selector requirements by node's fields.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            weight:\n                              description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.\n                              format: int32\n                              type: integer\n                          required:\n                          - preference\n                          - weight\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                      requiredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          If the affinity requirements specified by this field are not met at\n                          scheduling time, the pod will not be scheduled onto the node.\n                          If the affinity requirements specified by this field cease to be met\n                          at some point during pod execution (e.g. due to an update), the system\n                          may or may not try to eventually evict the pod from its node.\n                        properties:\n                          nodeSelectorTerms:\n                            description: Required. A list of node selector terms. The terms are ORed.\n                            items:\n                              description: |-\n                                A null or empty node selector term matches no objects. The requirements of\n                                them are ANDed.\n                                The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.\n                              properties:\n                                matchExpressions:\n                                  description: A list of node selector requirements by node's labels.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchFields:\n                                  description: A list of node selector requirements by node's fields.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                            x-kubernetes-list-type: atomic\n                        required:\n                        - nodeSelectorTerms\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  podAffinity:\n                    description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)).\n                    properties:\n                      preferredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          The scheduler will prefer to schedule pods to nodes that satisfy\n                          the affinity expressions specified by this field, but it may choose\n                          a node that violates one or more of the expressions. The node that is\n                          most preferred is the one with the greatest sum of weights, i.e.\n                          for each node that meets all of the scheduling requirements (resource\n                          request, requiredDuringScheduling affinity expressions, etc.),\n                          compute a sum by iterating through the elements of this field and adding\n                          \"weight\" to the sum if the node has pods which matches the corresponding podAffinityTerm; the\n                          node(s) with the highest sum are the most preferred.\n                        items:\n                          description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)\n                          properties:\n                            podAffinityTerm:\n                              description: Required. A pod affinity term, associated with the corresponding weight.\n                              properties:\n                                labelSelector:\n                                  description: |-\n                                    A label query over a set of resources, in this case pods.\n                                    If it's null, this PodAffinityTerm matches with no Pods.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                matchLabelKeys:\n                                  description: |-\n                                    MatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                    Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                mismatchLabelKeys:\n                                  description: |-\n                                    MismatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                    Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                namespaceSelector:\n                                  description: |-\n                                    A label query over the set of namespaces that the term applies to.\n                                    The term is applied to the union of the namespaces selected by this field\n                                    and the ones listed in the namespaces field.\n                                    null selector and null or empty namespaces list means \"this pod's namespace\".\n                                    An empty selector ({}) matches all namespaces.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                namespaces:\n                                  description: |-\n                                    namespaces specifies a static list of namespace names that the term applies to.\n                                    The term is applied to the union of the namespaces listed in this field\n                                    and the ones selected by namespaceSelector.\n                                    null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                topologyKey:\n                                  description: |-\n                                    This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                    the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                    whose value of the label with key topologyKey matches that of any node on which any of the\n                                    selected pods is running.\n                                    Empty topologyKey is not allowed.\n                                  type: string\n                              required:\n                              - topologyKey\n                              type: object\n                            weight:\n                              description: |-\n                                weight associated with matching the corresponding podAffinityTerm,\n                                in the range 1-100.\n                              format: int32\n                              type: integer\n                          required:\n                          - podAffinityTerm\n                          - weight\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                      requiredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          If the affinity requirements specified by this field are not met at\n                          scheduling time, the pod will not be scheduled onto the node.\n                          If the affinity requirements specified by this field cease to be met\n                          at some point during pod execution (e.g. due to a pod label update), the\n                          system may or may not try to eventually evict the pod from its node.\n                          When there are multiple elements, the lists of nodes corresponding to each\n                          podAffinityTerm are intersected, i.e. all terms must be satisfied.\n                        items:\n                          description: |-\n                            Defines a set of pods (namely those matching the labelSelector\n                            relative to the given namespace(s)) that this pod should be\n                            co-located (affinity) or not co-located (anti-affinity) with,\n                            where co-located is defined as running on a node whose value of\n                            the label with key <topologyKey> matches that of any node on which\n                            a pod of the set of pods is running\n                          properties:\n                            labelSelector:\n                              description: |-\n                                A label query over a set of resources, in this case pods.\n                                If it's null, this PodAffinityTerm matches with no Pods.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            matchLabelKeys:\n                              description: |-\n                                MatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            mismatchLabelKeys:\n                              description: |-\n                                MismatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            namespaceSelector:\n                              description: |-\n                                A label query over the set of namespaces that the term applies to.\n                                The term is applied to the union of the namespaces selected by this field\n                                and the ones listed in the namespaces field.\n                                null selector and null or empty namespaces list means \"this pod's namespace\".\n                                An empty selector ({}) matches all namespaces.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            namespaces:\n                              description: |-\n                                namespaces specifies a static list of namespace names that the term applies to.\n                                The term is applied to the union of the namespaces listed in this field\n                                and the ones selected by namespaceSelector.\n                                null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            topologyKey:\n                              description: |-\n                                This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                whose value of the label with key topologyKey matches that of any node on which any of the\n                                selected pods is running.\n                                Empty topologyKey is not allowed.\n                              type: string\n                          required:\n                          - topologyKey\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                    type: object\n                  podAntiAffinity:\n                    description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).\n                    properties:\n                      preferredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          The scheduler will prefer to schedule pods to nodes that satisfy\n                          the anti-affinity expressions specified by this field, but it may choose\n                          a node that violates one or more of the expressions. The node that is\n                          most preferred is the one with the greatest sum of weights, i.e.\n                          for each node that meets all of the scheduling requirements (resource\n                          request, requiredDuringScheduling anti-affinity expressions, etc.),\n                          compute a sum by iterating through the elements of this field and adding\n                          \"weight\" to the sum if the node has pods which matches the corresponding podAffinityTerm; the\n                          node(s) with the highest sum are the most preferred.\n                        items:\n                          description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)\n                          properties:\n                            podAffinityTerm:\n                              description: Required. A pod affinity term, associated with the corresponding weight.\n                              properties:\n                                labelSelector:\n                                  description: |-\n                                    A label query over a set of resources, in this case pods.\n                                    If it's null, this PodAffinityTerm matches with no Pods.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                matchLabelKeys:\n                                  description: |-\n                                    MatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                    Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                mismatchLabelKeys:\n                                  description: |-\n                                    MismatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                    Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                namespaceSelector:\n                                  description: |-\n                                    A label query over the set of namespaces that the term applies to.\n                                    The term is applied to the union of the namespaces selected by this field\n                                    and the ones listed in the namespaces field.\n                                    null selector and null or empty namespaces list means \"this pod's namespace\".\n                                    An empty selector ({}) matches all namespaces.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                namespaces:\n                                  description: |-\n                                    namespaces specifies a static list of namespace names that the term applies to.\n                                    The term is applied to the union of the namespaces listed in this field\n                                    and the ones selected by namespaceSelector.\n                                    null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                topologyKey:\n                                  description: |-\n                                    This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                    the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                    whose value of the label with key topologyKey matches that of any node on which any of the\n                                    selected pods is running.\n                                    Empty topologyKey is not allowed.\n                                  type: string\n                              required:\n                              - topologyKey\n                              type: object\n                            weight:\n                              description: |-\n                                weight associated with matching the corresponding podAffinityTerm,\n                                in the range 1-100.\n                              format: int32\n                              type: integer\n                          required:\n                          - podAffinityTerm\n                          - weight\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                      requiredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          If the anti-affinity requirements specified by this field are not met at\n                          scheduling time, the pod will not be scheduled onto the node.\n                          If the anti-affinity requirements specified by this field cease to be met\n                          at some point during pod execution (e.g. due to a pod label update), the\n                          system may or may not try to eventually evict the pod from its node.\n                          When there are multiple elements, the lists of nodes corresponding to each\n                          podAffinityTerm are intersected, i.e. all terms must be satisfied.\n                        items:\n                          description: |-\n                            Defines a set of pods (namely those matching the labelSelector\n                            relative to the given namespace(s)) that this pod should be\n                            co-located (affinity) or not co-located (anti-affinity) with,\n                            where co-located is defined as running on a node whose value of\n                            the label with key <topologyKey> matches that of any node on which\n                            a pod of the set of pods is running\n                          properties:\n                            labelSelector:\n                              description: |-\n                                A label query over a set of resources, in this case pods.\n                                If it's null, this PodAffinityTerm matches with no Pods.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            matchLabelKeys:\n                              description: |-\n                                MatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            mismatchLabelKeys:\n                              description: |-\n                                MismatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            namespaceSelector:\n                              description: |-\n                                A label query over the set of namespaces that the term applies to.\n                                The term is applied to the union of the namespaces selected by this field\n                                and the ones listed in the namespaces field.\n                                null selector and null or empty namespaces list means \"this pod's namespace\".\n                                An empty selector ({}) matches all namespaces.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            namespaces:\n                              description: |-\n                                namespaces specifies a static list of namespace names that the term applies to.\n                                The term is applied to the union of the namespaces listed in this field\n                                and the ones selected by namespaceSelector.\n                                null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            topologyKey:\n                              description: |-\n                                This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                whose value of the label with key topologyKey matches that of any node on which any of the\n                                selected pods is running.\n                                Empty topologyKey is not allowed.\n                              type: string\n                          required:\n                          - topologyKey\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                    type: object\n                type: object\n              apiserverConfig:\n                description: |-\n                  APIServerConfig allows specifying a host and auth methods to access the\n                  Kuberntees API server.\n                  If null, Prometheus is assumed to run inside of the cluster: it will\n                  discover the API servers automatically and use the Pod's CA certificate\n                  and bearer token file at /var/run/secrets/kubernetes.io/serviceaccount/.\n                properties:\n                  authorization:\n                    description: |-\n                      Authorization section for the API server.\n\n                      Cannot be set at the same time as `basicAuth`, `bearerToken`, or\n                      `bearerTokenFile`.\n                    properties:\n                      credentials:\n                        description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      credentialsFile:\n                        description: File to read a secret from, mutually exclusive with `credentials`.\n                        type: string\n                      type:\n                        description: |-\n                          Defines the authentication type. The value is case-insensitive.\n\n                          \"Basic\" is not a supported value.\n\n                          Default: \"Bearer\"\n                        type: string\n                    type: object\n                  basicAuth:\n                    description: |-\n                      BasicAuth configuration for the API server.\n\n                      Cannot be set at the same time as `authorization`, `bearerToken`, or\n                      `bearerTokenFile`.\n                    properties:\n                      password:\n                        description: |-\n                          `password` specifies a key of a Secret containing the password for\n                          authentication.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      username:\n                        description: |-\n                          `username` specifies a key of a Secret containing the username for\n                          authentication.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  bearerToken:\n                    description: |-\n                      *Warning: this field shouldn't be used because the token value appears\n                      in clear-text. Prefer using `authorization`.*\n\n                      Deprecated: this will be removed in a future release.\n                    type: string\n                  bearerTokenFile:\n                    description: |-\n                      File to read bearer token for accessing apiserver.\n\n                      Cannot be set at the same time as `basicAuth`, `authorization`, or `bearerToken`.\n\n                      Deprecated: this will be removed in a future release. Prefer using `authorization`.\n                    type: string\n                  host:\n                    description: |-\n                      Kubernetes API address consisting of a hostname or IP address followed\n                      by an optional port number.\n                    type: string\n                  noProxy:\n                    description: |-\n                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                      that should be excluded from proxying. IP and domain names can\n                      contain port numbers.\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: string\n                  proxyConnectHeader:\n                    additionalProperties:\n                      items:\n                        description: SecretKeySelector selects a key of a Secret.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      type: array\n                    description: |-\n                      ProxyConnectHeader optionally specifies headers to send to\n                      proxies during CONNECT requests.\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  proxyFromEnvironment:\n                    description: |-\n                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: boolean\n                  proxyUrl:\n                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                    pattern: ^(http|https|socks5)://.+$\n                    type: string\n                  tlsConfig:\n                    description: TLS Config to use for the API server.\n                    properties:\n                      ca:\n                        description: Certificate authority used when verifying server certificates.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      caFile:\n                        description: Path to the CA cert in the Prometheus container to use for the targets.\n                        type: string\n                      cert:\n                        description: Client certificate to present when doing client-authentication.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      certFile:\n                        description: Path to the client cert file in the Prometheus container for the targets.\n                        type: string\n                      insecureSkipVerify:\n                        description: Disable target certificate validation.\n                        type: boolean\n                      keyFile:\n                        description: Path to the client key file in the Prometheus container for the targets.\n                        type: string\n                      keySecret:\n                        description: Secret containing the client key file for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: |-\n                          Maximum acceptable TLS version.\n\n                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      minVersion:\n                        description: |-\n                          Minimum acceptable TLS version.\n\n                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      serverName:\n                        description: Used to verify the hostname for the targets.\n                        type: string\n                    type: object\n                required:\n                - host\n                type: object\n              arbitraryFSAccessThroughSMs:\n                description: |-\n                  When true, ServiceMonitor, PodMonitor and Probe object are forbidden to\n                  reference arbitrary files on the file system of the 'prometheus'\n                  container.\n                  When a ServiceMonitor's endpoint specifies a `bearerTokenFile` value\n                  (e.g.  '/var/run/secrets/kubernetes.io/serviceaccount/token'), a\n                  malicious target can get access to the Prometheus service account's\n                  token in the Prometheus' scrape request. Setting\n                  `spec.arbitraryFSAccessThroughSM` to 'true' would prevent the attack.\n                  Users should instead provide the credentials using the\n                  `spec.bearerTokenSecret` field.\n                properties:\n                  deny:\n                    type: boolean\n                type: object\n              automountServiceAccountToken:\n                description: |-\n                  AutomountServiceAccountToken indicates whether a service account token should be automatically mounted in the pod.\n                  If the field isn't set, the operator mounts the service account token by default.\n\n                  **Warning:** be aware that by default, Prometheus requires the service account token for Kubernetes service discovery.\n                  It is possible to use strategic merge patch to project the service account token into the 'prometheus' container.\n                type: boolean\n              bodySizeLimit:\n                description: |-\n                  BodySizeLimit defines per-scrape on response body size.\n                  Only valid in Prometheus versions 2.45.0 and newer.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedBodySizeLimit.\n                pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$\n                type: string\n              configMaps:\n                description: |-\n                  ConfigMaps is a list of ConfigMaps in the same namespace as the Prometheus\n                  object, which shall be mounted into the Prometheus Pods.\n                  Each ConfigMap is added to the StatefulSet definition as a volume named `configmap-<configmap-name>`.\n                  The ConfigMaps are mounted into /etc/prometheus/configmaps/<configmap-name> in the 'prometheus' container.\n                items:\n                  type: string\n                type: array\n              containers:\n                description: |-\n                  Containers allows injecting additional containers or modifying operator\n                  generated containers. This can be used to allow adding an authentication\n                  proxy to the Pods or to change the behavior of an operator generated\n                  container. Containers described here modify an operator generated\n                  container if they share the same name and modifications are done via a\n                  strategic merge patch.\n\n                  The names of containers managed by the operator are:\n                  * `prometheus`\n                  * `config-reloader`\n                  * `thanos-sidecar`\n\n                  Overriding containers is entirely outside the scope of what the\n                  maintainers will support and by doing so, you accept that this behaviour\n                  may break at any time without notice.\n                items:\n                  description: A single application container that you want to run within a pod.\n                  properties:\n                    args:\n                      description: |-\n                        Arguments to the entrypoint.\n                        The container image's CMD is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    command:\n                      description: |-\n                        Entrypoint array. Not executed within a shell.\n                        The container image's ENTRYPOINT is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    env:\n                      description: |-\n                        List of environment variables to set in the container.\n                        Cannot be updated.\n                      items:\n                        description: EnvVar represents an environment variable present in a Container.\n                        properties:\n                          name:\n                            description: Name of the environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          value:\n                            description: |-\n                              Variable references $(VAR_NAME) are expanded\n                              using the previously defined environment variables in the container and\n                              any service environment variables. If a variable cannot be resolved,\n                              the reference in the input string will be unchanged. Double $$ are reduced\n                              to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.\n                              \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\".\n                              Escaped references will never be expanded, regardless of whether the variable\n                              exists or not.\n                              Defaults to \"\".\n                            type: string\n                          valueFrom:\n                            description: Source for the environment variable's value. Cannot be used if value is not empty.\n                            properties:\n                              configMapKeyRef:\n                                description: Selects a key of a ConfigMap.\n                                properties:\n                                  key:\n                                    description: The key to select.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the ConfigMap or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              fieldRef:\n                                description: |-\n                                  Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,\n                                  spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.\n                                properties:\n                                  apiVersion:\n                                    description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                    type: string\n                                  fieldPath:\n                                    description: Path of the field to select in the specified API version.\n                                    type: string\n                                required:\n                                - fieldPath\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              resourceFieldRef:\n                                description: |-\n                                  Selects a resource of the container: only resources limits and requests\n                                  (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.\n                                properties:\n                                  containerName:\n                                    description: 'Container name: required for volumes, optional for env vars'\n                                    type: string\n                                  divisor:\n                                    anyOf:\n                                    - type: integer\n                                    - type: string\n                                    description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                    x-kubernetes-int-or-string: true\n                                  resource:\n                                    description: 'Required: resource to select'\n                                    type: string\n                                required:\n                                - resource\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              secretKeyRef:\n                                description: Selects a key of a secret in the pod's namespace\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            type: object\n                        required:\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - name\n                      x-kubernetes-list-type: map\n                    envFrom:\n                      description: |-\n                        List of sources to populate environment variables in the container.\n                        The keys defined within a source must be a C_IDENTIFIER. All invalid keys\n                        will be reported as an event when the container is starting. When a key exists in multiple\n                        sources, the value associated with the last source will take precedence.\n                        Values defined by an Env with a duplicate key will take precedence.\n                        Cannot be updated.\n                      items:\n                        description: EnvFromSource represents the source of a set of ConfigMaps or Secrets\n                        properties:\n                          configMapRef:\n                            description: The ConfigMap to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          prefix:\n                            description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          secretRef:\n                            description: The Secret to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    image:\n                      description: |-\n                        Container image name.\n                        More info: https://kubernetes.io/docs/concepts/containers/images\n                        This field is optional to allow higher level config management to default or override\n                        container images in workload controllers like Deployments and StatefulSets.\n                      type: string\n                    imagePullPolicy:\n                      description: |-\n                        Image pull policy.\n                        One of Always, Never, IfNotPresent.\n                        Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/containers/images#updating-images\n                      type: string\n                    lifecycle:\n                      description: |-\n                        Actions that the management system should take in response to container lifecycle events.\n                        Cannot be updated.\n                      properties:\n                        postStart:\n                          description: |-\n                            PostStart is called immediately after a container is created. If the handler fails,\n                            the container is terminated and restarted according to its restart policy.\n                            Other management of the container blocks until the hook completes.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        preStop:\n                          description: |-\n                            PreStop is called immediately before a container is terminated due to an\n                            API request or management event such as liveness/startup probe failure,\n                            preemption, resource contention, etc. The handler is not called if the\n                            container crashes or exits. The Pod's termination grace period countdown begins before the\n                            PreStop hook is executed. Regardless of the outcome of the handler, the\n                            container will eventually terminate within the Pod's termination grace\n                            period (unless delayed by finalizers). Other management of the container blocks until the hook completes\n                            or until the termination grace period is reached.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        stopSignal:\n                          description: |-\n                            StopSignal defines which signal will be sent to a container when it is being stopped.\n                            If not specified, the default is defined by the container runtime in use.\n                            StopSignal can only be set for Pods with a non-empty .spec.os.name\n                          type: string\n                      type: object\n                    livenessProbe:\n                      description: |-\n                        Periodic probe of container liveness.\n                        Container will be restarted if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    name:\n                      description: |-\n                        Name of the container specified as a DNS_LABEL.\n                        Each container in a pod must have a unique name (DNS_LABEL).\n                        Cannot be updated.\n                      type: string\n                    ports:\n                      description: |-\n                        List of ports to expose from the container. Not specifying a port here\n                        DOES NOT prevent that port from being exposed. Any port which is\n                        listening on the default \"0.0.0.0\" address inside a container will be\n                        accessible from the network.\n                        Modifying this array with strategic merge patch may corrupt the data.\n                        For more information See https://github.com/kubernetes/kubernetes/issues/108255.\n                        Cannot be updated.\n                      items:\n                        description: ContainerPort represents a network port in a single container.\n                        properties:\n                          containerPort:\n                            description: |-\n                              Number of port to expose on the pod's IP address.\n                              This must be a valid port number, 0 < x < 65536.\n                            format: int32\n                            type: integer\n                          hostIP:\n                            description: What host IP to bind the external port to.\n                            type: string\n                          hostPort:\n                            description: |-\n                              Number of port to expose on the host.\n                              If specified, this must be a valid port number, 0 < x < 65536.\n                              If HostNetwork is specified, this must match ContainerPort.\n                              Most containers do not need this.\n                            format: int32\n                            type: integer\n                          name:\n                            description: |-\n                              If specified, this must be an IANA_SVC_NAME and unique within the pod. Each\n                              named port in a pod must have a unique name. Name for the port that can be\n                              referred to by services.\n                            type: string\n                          protocol:\n                            default: TCP\n                            description: |-\n                              Protocol for port. Must be UDP, TCP, or SCTP.\n                              Defaults to \"TCP\".\n                            type: string\n                        required:\n                        - containerPort\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - containerPort\n                      - protocol\n                      x-kubernetes-list-type: map\n                    readinessProbe:\n                      description: |-\n                        Periodic probe of container service readiness.\n                        Container will be removed from service endpoints if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    resizePolicy:\n                      description: Resources resize policy for the container.\n                      items:\n                        description: ContainerResizePolicy represents resource resize policy for the container.\n                        properties:\n                          resourceName:\n                            description: |-\n                              Name of the resource to which this resource resize policy applies.\n                              Supported values: cpu, memory.\n                            type: string\n                          restartPolicy:\n                            description: |-\n                              Restart policy to apply when specified resource is resized.\n                              If not specified, it defaults to NotRequired.\n                            type: string\n                        required:\n                        - resourceName\n                        - restartPolicy\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    resources:\n                      description: |-\n                        Compute Resources required by this container.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                      properties:\n                        claims:\n                          description: |-\n                            Claims lists the names of resources, defined in spec.resourceClaims,\n                            that are used by this container.\n\n                            This is an alpha field and requires enabling the\n                            DynamicResourceAllocation feature gate.\n\n                            This field is immutable. It can only be set for containers.\n                          items:\n                            description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                            properties:\n                              name:\n                                description: |-\n                                  Name must match the name of one entry in pod.spec.resourceClaims of\n                                  the Pod where this field is used. It makes that resource available\n                                  inside a container.\n                                type: string\n                              request:\n                                description: |-\n                                  Request is the name chosen for a request in the referenced claim.\n                                  If empty, everything from the claim is made available, otherwise\n                                  only the result of this request.\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          type: array\n                          x-kubernetes-list-map-keys:\n                          - name\n                          x-kubernetes-list-type: map\n                        limits:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Limits describes the maximum amount of compute resources allowed.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                        requests:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Requests describes the minimum amount of compute resources required.\n                            If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                            otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                      type: object\n                    restartPolicy:\n                      description: |-\n                        RestartPolicy defines the restart behavior of individual containers in a pod.\n                        This field may only be set for init containers, and the only allowed value is \"Always\".\n                        For non-init containers or when this field is not specified,\n                        the restart behavior is defined by the Pod's restart policy and the container type.\n                        Setting the RestartPolicy as \"Always\" for the init container will have the following effect:\n                        this init container will be continually restarted on\n                        exit until all regular containers have terminated. Once all regular\n                        containers have completed, all init containers with restartPolicy \"Always\"\n                        will be shut down. This lifecycle differs from normal init containers and\n                        is often referred to as a \"sidecar\" container. Although this init\n                        container still starts in the init container sequence, it does not wait\n                        for the container to complete before proceeding to the next init\n                        container. Instead, the next init container starts immediately after this\n                        init container is started, or after any startupProbe has successfully\n                        completed.\n                      type: string\n                    securityContext:\n                      description: |-\n                        SecurityContext defines the security options the container should be run with.\n                        If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.\n                        More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/\n                      properties:\n                        allowPrivilegeEscalation:\n                          description: |-\n                            AllowPrivilegeEscalation controls whether a process can gain more\n                            privileges than its parent process. This bool directly controls if\n                            the no_new_privs flag will be set on the container process.\n                            AllowPrivilegeEscalation is true always when the container is:\n                            1) run as Privileged\n                            2) has CAP_SYS_ADMIN\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        appArmorProfile:\n                          description: |-\n                            appArmorProfile is the AppArmor options to use by this container. If set, this profile\n                            overrides the pod's appArmorProfile.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile loaded on the node that should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must match the loaded name of the profile.\n                                Must be set if and only if type is \"Localhost\".\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of AppArmor profile will be applied.\n                                Valid options are:\n                                  Localhost - a profile pre-loaded on the node.\n                                  RuntimeDefault - the container runtime's default profile.\n                                  Unconfined - no AppArmor enforcement.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        capabilities:\n                          description: |-\n                            The capabilities to add/drop when running containers.\n                            Defaults to the default set of capabilities granted by the container runtime.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            add:\n                              description: Added capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            drop:\n                              description: Removed capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        privileged:\n                          description: |-\n                            Run container in privileged mode.\n                            Processes in privileged containers are essentially equivalent to root on the host.\n                            Defaults to false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        procMount:\n                          description: |-\n                            procMount denotes the type of proc mount to use for the containers.\n                            The default value is Default which uses the container runtime defaults for\n                            readonly paths and masked paths.\n                            This requires the ProcMountType feature flag to be enabled.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: string\n                        readOnlyRootFilesystem:\n                          description: |-\n                            Whether this container has a read-only root filesystem.\n                            Default is false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        runAsGroup:\n                          description: |-\n                            The GID to run the entrypoint of the container process.\n                            Uses runtime default if unset.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        runAsNonRoot:\n                          description: |-\n                            Indicates that the container must run as a non-root user.\n                            If true, the Kubelet will validate the image at runtime to ensure that it\n                            does not run as UID 0 (root) and fail to start the container if it does.\n                            If unset or false, no such validation will be performed.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                          type: boolean\n                        runAsUser:\n                          description: |-\n                            The UID to run the entrypoint of the container process.\n                            Defaults to user specified in image metadata if unspecified.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        seLinuxOptions:\n                          description: |-\n                            The SELinux context to be applied to the container.\n                            If unspecified, the container runtime will allocate a random SELinux context for each\n                            container.  May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            level:\n                              description: Level is SELinux level label that applies to the container.\n                              type: string\n                            role:\n                              description: Role is a SELinux role label that applies to the container.\n                              type: string\n                            type:\n                              description: Type is a SELinux type label that applies to the container.\n                              type: string\n                            user:\n                              description: User is a SELinux user label that applies to the container.\n                              type: string\n                          type: object\n                        seccompProfile:\n                          description: |-\n                            The seccomp options to use by this container. If seccomp options are\n                            provided at both the pod & container level, the container options\n                            override the pod options.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile defined in a file on the node should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must be a descending path, relative to the kubelet's configured seccomp profile location.\n                                Must be set if type is \"Localhost\". Must NOT be set for any other type.\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of seccomp profile will be applied.\n                                Valid options are:\n\n                                Localhost - a profile defined in a file on the node should be used.\n                                RuntimeDefault - the container runtime default profile should be used.\n                                Unconfined - no profile should be applied.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        windowsOptions:\n                          description: |-\n                            The Windows specific settings applied to all containers.\n                            If unspecified, the options from the PodSecurityContext will be used.\n                            If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is linux.\n                          properties:\n                            gmsaCredentialSpec:\n                              description: |-\n                                GMSACredentialSpec is where the GMSA admission webhook\n                                (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the\n                                GMSA credential spec named by the GMSACredentialSpecName field.\n                              type: string\n                            gmsaCredentialSpecName:\n                              description: GMSACredentialSpecName is the name of the GMSA credential spec to use.\n                              type: string\n                            hostProcess:\n                              description: |-\n                                HostProcess determines if a container should be run as a 'Host Process' container.\n                                All of a Pod's containers must have the same effective HostProcess value\n                                (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).\n                                In addition, if HostProcess is true then HostNetwork must also be set to true.\n                              type: boolean\n                            runAsUserName:\n                              description: |-\n                                The UserName in Windows to run the entrypoint of the container process.\n                                Defaults to the user specified in image metadata if unspecified.\n                                May also be set in PodSecurityContext. If set in both SecurityContext and\n                                PodSecurityContext, the value specified in SecurityContext takes precedence.\n                              type: string\n                          type: object\n                      type: object\n                    startupProbe:\n                      description: |-\n                        StartupProbe indicates that the Pod has successfully initialized.\n                        If specified, no other probes are executed until this completes successfully.\n                        If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.\n                        This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,\n                        when it might take a long time to load data or warm a cache, than during steady-state operation.\n                        This cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    stdin:\n                      description: |-\n                        Whether this container should allocate a buffer for stdin in the container runtime. If this\n                        is not set, reads from stdin in the container will always result in EOF.\n                        Default is false.\n                      type: boolean\n                    stdinOnce:\n                      description: |-\n                        Whether the container runtime should close the stdin channel after it has been opened by\n                        a single attach. When stdin is true the stdin stream will remain open across multiple attach\n                        sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the\n                        first client attaches to stdin, and then remains open and accepts data until the client disconnects,\n                        at which time stdin is closed and remains closed until the container is restarted. If this\n                        flag is false, a container processes that reads from stdin will never receive an EOF.\n                        Default is false\n                      type: boolean\n                    terminationMessagePath:\n                      description: |-\n                        Optional: Path at which the file to which the container's termination message\n                        will be written is mounted into the container's filesystem.\n                        Message written is intended to be brief final status, such as an assertion failure message.\n                        Will be truncated by the node if greater than 4096 bytes. The total message length across\n                        all containers will be limited to 12kb.\n                        Defaults to /dev/termination-log.\n                        Cannot be updated.\n                      type: string\n                    terminationMessagePolicy:\n                      description: |-\n                        Indicate how the termination message should be populated. File will use the contents of\n                        terminationMessagePath to populate the container status message on both success and failure.\n                        FallbackToLogsOnError will use the last chunk of container log output if the termination\n                        message file is empty and the container exited with an error.\n                        The log output is limited to 2048 bytes or 80 lines, whichever is smaller.\n                        Defaults to File.\n                        Cannot be updated.\n                      type: string\n                    tty:\n                      description: |-\n                        Whether this container should allocate a TTY for itself, also requires 'stdin' to be true.\n                        Default is false.\n                      type: boolean\n                    volumeDevices:\n                      description: volumeDevices is the list of block devices to be used by the container.\n                      items:\n                        description: volumeDevice describes a mapping of a raw block device within a container.\n                        properties:\n                          devicePath:\n                            description: devicePath is the path inside of the container that the device will be mapped to.\n                            type: string\n                          name:\n                            description: name must match the name of a persistentVolumeClaim in the pod\n                            type: string\n                        required:\n                        - devicePath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - devicePath\n                      x-kubernetes-list-type: map\n                    volumeMounts:\n                      description: |-\n                        Pod volumes to mount into the container's filesystem.\n                        Cannot be updated.\n                      items:\n                        description: VolumeMount describes a mounting of a Volume within a container.\n                        properties:\n                          mountPath:\n                            description: |-\n                              Path within the container at which the volume should be mounted.  Must\n                              not contain ':'.\n                            type: string\n                          mountPropagation:\n                            description: |-\n                              mountPropagation determines how mounts are propagated from the host\n                              to container and the other way around.\n                              When not set, MountPropagationNone is used.\n                              This field is beta in 1.10.\n                              When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                              (which defaults to None).\n                            type: string\n                          name:\n                            description: This must match the Name of a Volume.\n                            type: string\n                          readOnly:\n                            description: |-\n                              Mounted read-only if true, read-write otherwise (false or unspecified).\n                              Defaults to false.\n                            type: boolean\n                          recursiveReadOnly:\n                            description: |-\n                              RecursiveReadOnly specifies whether read-only mounts should be handled\n                              recursively.\n\n                              If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                              If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                              recursively read-only.  If this field is set to IfPossible, the mount is made\n                              recursively read-only, if it is supported by the container runtime.  If this\n                              field is set to Enabled, the mount is made recursively read-only if it is\n                              supported by the container runtime, otherwise the pod will not be started and\n                              an error will be generated to indicate the reason.\n\n                              If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                              None (or be unspecified, which defaults to None).\n\n                              If this field is not specified, it is treated as an equivalent of Disabled.\n                            type: string\n                          subPath:\n                            description: |-\n                              Path within the volume from which the container's volume should be mounted.\n                              Defaults to \"\" (volume's root).\n                            type: string\n                          subPathExpr:\n                            description: |-\n                              Expanded path within the volume from which the container's volume should be mounted.\n                              Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                              Defaults to \"\" (volume's root).\n                              SubPathExpr and SubPath are mutually exclusive.\n                            type: string\n                        required:\n                        - mountPath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - mountPath\n                      x-kubernetes-list-type: map\n                    workingDir:\n                      description: |-\n                        Container's working directory.\n                        If not specified, the container runtime's default will be used, which\n                        might be configured in the container image.\n                        Cannot be updated.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                type: array\n              convertClassicHistogramsToNHCB:\n                description: |-\n                  Whether to convert all scraped classic histograms into a native\n                  histogram with custom buckets.\n\n                  It requires Prometheus >= v3.4.0.\n                type: boolean\n              dnsConfig:\n                description: Defines the DNS configuration for the pods.\n                properties:\n                  nameservers:\n                    description: |-\n                      A list of DNS name server IP addresses.\n                      This will be appended to the base nameservers generated from DNSPolicy.\n                    items:\n                      minLength: 1\n                      type: string\n                    type: array\n                    x-kubernetes-list-type: set\n                  options:\n                    description: |-\n                      A list of DNS resolver options.\n                      This will be merged with the base options generated from DNSPolicy.\n                      Resolution options given in Options\n                      will override those that appear in the base DNSPolicy.\n                    items:\n                      description: PodDNSConfigOption defines DNS resolver options of a pod.\n                      properties:\n                        name:\n                          description: Name is required and must be unique.\n                          minLength: 1\n                          type: string\n                        value:\n                          description: Value is optional.\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    type: array\n                    x-kubernetes-list-map-keys:\n                    - name\n                    x-kubernetes-list-type: map\n                  searches:\n                    description: |-\n                      A list of DNS search domains for host-name lookup.\n                      This will be appended to the base search paths generated from DNSPolicy.\n                    items:\n                      minLength: 1\n                      type: string\n                    type: array\n                    x-kubernetes-list-type: set\n                type: object\n              dnsPolicy:\n                description: Defines the DNS policy for the pods.\n                enum:\n                - ClusterFirstWithHostNet\n                - ClusterFirst\n                - Default\n                - None\n                type: string\n              enableFeatures:\n                description: |-\n                  Enable access to Prometheus feature flags. By default, no features are enabled.\n\n                  Enabling features which are disabled by default is entirely outside the\n                  scope of what the maintainers will support and by doing so, you accept\n                  that this behaviour may break at any time without notice.\n\n                  For more information see https://prometheus.io/docs/prometheus/latest/feature_flags/\n                items:\n                  minLength: 1\n                  type: string\n                type: array\n                x-kubernetes-list-type: set\n              enableOTLPReceiver:\n                description: |-\n                  Enable Prometheus to be used as a receiver for the OTLP Metrics protocol.\n\n                  Note that the OTLP receiver endpoint is automatically enabled if `.spec.otlpConfig` is defined.\n\n                  It requires Prometheus >= v2.47.0.\n                type: boolean\n              enableRemoteWriteReceiver:\n                description: |-\n                  Enable Prometheus to be used as a receiver for the Prometheus remote\n                  write protocol.\n\n                  WARNING: This is not considered an efficient way of ingesting samples.\n                  Use it with caution for specific low-volume use cases.\n                  It is not suitable for replacing the ingestion via scraping and turning\n                  Prometheus into a push-based metrics collection system.\n                  For more information see https://prometheus.io/docs/prometheus/latest/querying/api/#remote-write-receiver\n\n                  It requires Prometheus >= v2.33.0.\n                type: boolean\n              enableServiceLinks:\n                description: Indicates whether information about services should be injected into pod's environment variables\n                type: boolean\n              enforcedBodySizeLimit:\n                description: |-\n                  When defined, enforcedBodySizeLimit specifies a global limit on the size\n                  of uncompressed response body that will be accepted by Prometheus.\n                  Targets responding with a body larger than this many bytes will cause\n                  the scrape to fail.\n\n                  It requires Prometheus >= v2.28.0.\n\n                  When both `enforcedBodySizeLimit` and `bodySizeLimit` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined bodySizeLimit value will inherit the global bodySizeLimit value (Prometheus >= 2.45.0) or the enforcedBodySizeLimit value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedBodySizeLimit` is greater than the `bodySizeLimit`, the `bodySizeLimit` will be set to `enforcedBodySizeLimit`.\n                  * Scrape objects with a bodySizeLimit value less than or equal to enforcedBodySizeLimit keep their specific value.\n                  * Scrape objects with a bodySizeLimit value greater than enforcedBodySizeLimit are set to enforcedBodySizeLimit.\n                pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$\n                type: string\n              enforcedKeepDroppedTargets:\n                description: |-\n                  When defined, enforcedKeepDroppedTargets specifies a global limit on the number of targets\n                  dropped by relabeling that will be kept in memory. The value overrides\n                  any `spec.keepDroppedTargets` set by\n                  ServiceMonitor, PodMonitor, Probe objects unless `spec.keepDroppedTargets` is\n                  greater than zero and less than `spec.enforcedKeepDroppedTargets`.\n\n                  It requires Prometheus >= v2.47.0.\n\n                  When both `enforcedKeepDroppedTargets` and `keepDroppedTargets` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined keepDroppedTargets value will inherit the global keepDroppedTargets value (Prometheus >= 2.45.0) or the enforcedKeepDroppedTargets value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedKeepDroppedTargets` is greater than the `keepDroppedTargets`, the `keepDroppedTargets` will be set to `enforcedKeepDroppedTargets`.\n                  * Scrape objects with a keepDroppedTargets value less than or equal to enforcedKeepDroppedTargets keep their specific value.\n                  * Scrape objects with a keepDroppedTargets value greater than enforcedKeepDroppedTargets are set to enforcedKeepDroppedTargets.\n                format: int64\n                type: integer\n              enforcedLabelLimit:\n                description: |-\n                  When defined, enforcedLabelLimit specifies a global limit on the number\n                  of labels per sample. The value overrides any `spec.labelLimit` set by\n                  ServiceMonitor, PodMonitor, Probe objects unless `spec.labelLimit` is\n                  greater than zero and less than `spec.enforcedLabelLimit`.\n\n                  It requires Prometheus >= v2.27.0.\n\n                  When both `enforcedLabelLimit` and `labelLimit` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined labelLimit value will inherit the global labelLimit value (Prometheus >= 2.45.0) or the enforcedLabelLimit value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedLabelLimit` is greater than the `labelLimit`, the `labelLimit` will be set to `enforcedLabelLimit`.\n                  * Scrape objects with a labelLimit value less than or equal to enforcedLabelLimit keep their specific value.\n                  * Scrape objects with a labelLimit value greater than enforcedLabelLimit are set to enforcedLabelLimit.\n                format: int64\n                type: integer\n              enforcedLabelNameLengthLimit:\n                description: |-\n                  When defined, enforcedLabelNameLengthLimit specifies a global limit on the length\n                  of labels name per sample. The value overrides any `spec.labelNameLengthLimit` set by\n                  ServiceMonitor, PodMonitor, Probe objects unless `spec.labelNameLengthLimit` is\n                  greater than zero and less than `spec.enforcedLabelNameLengthLimit`.\n\n                  It requires Prometheus >= v2.27.0.\n\n                  When both `enforcedLabelNameLengthLimit` and `labelNameLengthLimit` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined labelNameLengthLimit value will inherit the global labelNameLengthLimit value (Prometheus >= 2.45.0) or the enforcedLabelNameLengthLimit value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedLabelNameLengthLimit` is greater than the `labelNameLengthLimit`, the `labelNameLengthLimit` will be set to `enforcedLabelNameLengthLimit`.\n                  * Scrape objects with a labelNameLengthLimit value less than or equal to enforcedLabelNameLengthLimit keep their specific value.\n                  * Scrape objects with a labelNameLengthLimit value greater than enforcedLabelNameLengthLimit are set to enforcedLabelNameLengthLimit.\n                format: int64\n                type: integer\n              enforcedLabelValueLengthLimit:\n                description: |-\n                  When not null, enforcedLabelValueLengthLimit defines a global limit on the length\n                  of labels value per sample. The value overrides any `spec.labelValueLengthLimit` set by\n                  ServiceMonitor, PodMonitor, Probe objects unless `spec.labelValueLengthLimit` is\n                  greater than zero and less than `spec.enforcedLabelValueLengthLimit`.\n\n                  It requires Prometheus >= v2.27.0.\n\n                  When both `enforcedLabelValueLengthLimit` and `labelValueLengthLimit` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined labelValueLengthLimit value will inherit the global labelValueLengthLimit value (Prometheus >= 2.45.0) or the enforcedLabelValueLengthLimit value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedLabelValueLengthLimit` is greater than the `labelValueLengthLimit`, the `labelValueLengthLimit` will be set to `enforcedLabelValueLengthLimit`.\n                  * Scrape objects with a labelValueLengthLimit value less than or equal to enforcedLabelValueLengthLimit keep their specific value.\n                  * Scrape objects with a labelValueLengthLimit value greater than enforcedLabelValueLengthLimit are set to enforcedLabelValueLengthLimit.\n                format: int64\n                type: integer\n              enforcedNamespaceLabel:\n                description: |-\n                  When not empty, a label will be added to:\n\n                  1. All metrics scraped from `ServiceMonitor`, `PodMonitor`, `Probe` and `ScrapeConfig` objects.\n                  2. All metrics generated from recording rules defined in `PrometheusRule` objects.\n                  3. All alerts generated from alerting rules defined in `PrometheusRule` objects.\n                  4. All vector selectors of PromQL expressions defined in `PrometheusRule` objects.\n\n                  The label will not added for objects referenced in `spec.excludedFromEnforcement`.\n\n                  The label's name is this field's value.\n                  The label's value is the namespace of the `ServiceMonitor`,\n                  `PodMonitor`, `Probe`, `PrometheusRule` or `ScrapeConfig` object.\n                type: string\n              enforcedSampleLimit:\n                description: |-\n                  When defined, enforcedSampleLimit specifies a global limit on the number\n                  of scraped samples that will be accepted. This overrides any\n                  `spec.sampleLimit` set by ServiceMonitor, PodMonitor, Probe objects\n                  unless `spec.sampleLimit` is greater than zero and less than\n                  `spec.enforcedSampleLimit`.\n\n                  It is meant to be used by admins to keep the overall number of\n                  samples/series under a desired limit.\n\n                  When both `enforcedSampleLimit` and `sampleLimit` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined sampleLimit value will inherit the global sampleLimit value (Prometheus >= 2.45.0) or the enforcedSampleLimit value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedSampleLimit` is greater than the `sampleLimit`, the `sampleLimit` will be set to `enforcedSampleLimit`.\n                  * Scrape objects with a sampleLimit value less than or equal to enforcedSampleLimit keep their specific value.\n                  * Scrape objects with a sampleLimit value greater than enforcedSampleLimit are set to enforcedSampleLimit.\n                format: int64\n                type: integer\n              enforcedTargetLimit:\n                description: |-\n                  When defined, enforcedTargetLimit specifies a global limit on the number\n                  of scraped targets. The value overrides any `spec.targetLimit` set by\n                  ServiceMonitor, PodMonitor, Probe objects unless `spec.targetLimit` is\n                  greater than zero and less than `spec.enforcedTargetLimit`.\n\n                  It is meant to be used by admins to to keep the overall number of\n                  targets under a desired limit.\n\n                  When both `enforcedTargetLimit` and `targetLimit` are defined and greater than zero, the following rules apply:\n                  * Scrape objects without a defined targetLimit value will inherit the global targetLimit value (Prometheus >= 2.45.0) or the enforcedTargetLimit value (Prometheus < v2.45.0).\n                    If Prometheus version is >= 2.45.0 and the `enforcedTargetLimit` is greater than the `targetLimit`, the `targetLimit` will be set to `enforcedTargetLimit`.\n                  * Scrape objects with a targetLimit value less than or equal to enforcedTargetLimit keep their specific value.\n                  * Scrape objects with a targetLimit value greater than enforcedTargetLimit are set to enforcedTargetLimit.\n                format: int64\n                type: integer\n              excludedFromEnforcement:\n                description: |-\n                  List of references to PodMonitor, ServiceMonitor, Probe and PrometheusRule objects\n                  to be excluded from enforcing a namespace label of origin.\n\n                  It is only applicable if `spec.enforcedNamespaceLabel` set to true.\n                items:\n                  description: ObjectReference references a PodMonitor, ServiceMonitor, Probe or PrometheusRule object.\n                  properties:\n                    group:\n                      default: monitoring.coreos.com\n                      description: Group of the referent. When not specified, it defaults to `monitoring.coreos.com`\n                      enum:\n                      - monitoring.coreos.com\n                      type: string\n                    name:\n                      description: Name of the referent. When not set, all resources in the namespace are matched.\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace of the referent.\n                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/\n                      minLength: 1\n                      type: string\n                    resource:\n                      description: Resource of the referent.\n                      enum:\n                      - prometheusrules\n                      - servicemonitors\n                      - podmonitors\n                      - probes\n                      - scrapeconfigs\n                      type: string\n                  required:\n                  - namespace\n                  - resource\n                  type: object\n                type: array\n              externalLabels:\n                additionalProperties:\n                  type: string\n                description: |-\n                  The labels to add to any time series or alerts when communicating with\n                  external systems (federation, remote storage, Alertmanager).\n                  Labels defined by `spec.replicaExternalLabelName` and\n                  `spec.prometheusExternalLabelName` take precedence over this list.\n                type: object\n              externalUrl:\n                description: |-\n                  The external URL under which the Prometheus service is externally\n                  available. This is necessary to generate correct URLs (for instance if\n                  Prometheus is accessible behind an Ingress resource).\n                type: string\n              hostAliases:\n                description: |-\n                  Optional list of hosts and IPs that will be injected into the Pod's\n                  hosts file if specified.\n                items:\n                  description: |-\n                    HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the\n                    pod's hosts file.\n                  properties:\n                    hostnames:\n                      description: Hostnames for the above IP address.\n                      items:\n                        type: string\n                      type: array\n                    ip:\n                      description: IP address of the host file entry.\n                      type: string\n                  required:\n                  - hostnames\n                  - ip\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - ip\n                x-kubernetes-list-type: map\n              hostNetwork:\n                description: |-\n                  Use the host's network namespace if true.\n\n                  Make sure to understand the security implications if you want to enable\n                  it (https://kubernetes.io/docs/concepts/configuration/overview/ ).\n\n                  When hostNetwork is enabled, this will set the DNS policy to\n                  `ClusterFirstWithHostNet` automatically (unless `.spec.DNSPolicy` is set\n                  to a different value).\n                type: boolean\n              hostUsers:\n                description: |-\n                  HostUsers supports the user space in Kubernetes.\n\n                  More info: https://kubernetes.io/docs/tasks/configure-pod-container/user-namespaces/\n\n                  The feature requires at least Kubernetes 1.28 with the `UserNamespacesSupport` feature gate enabled.\n                  Starting Kubernetes 1.33, the feature is enabled by default.\n                type: boolean\n              ignoreNamespaceSelectors:\n                description: |-\n                  When true, `spec.namespaceSelector` from all PodMonitor, ServiceMonitor\n                  and Probe objects will be ignored. They will only discover targets\n                  within the namespace of the PodMonitor, ServiceMonitor and Probe\n                  object.\n                type: boolean\n              image:\n                description: |-\n                  Container image name for Prometheus. If specified, it takes precedence\n                  over the `spec.baseImage`, `spec.tag` and `spec.sha` fields.\n\n                  Specifying `spec.version` is still necessary to ensure the Prometheus\n                  Operator knows which version of Prometheus is being configured.\n\n                  If neither `spec.image` nor `spec.baseImage` are defined, the operator\n                  will use the latest upstream version of Prometheus available at the time\n                  when the operator was released.\n                type: string\n              imagePullPolicy:\n                description: |-\n                  Image pull policy for the 'prometheus', 'init-config-reloader' and 'config-reloader' containers.\n                  See https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy for more details.\n                enum:\n                - \"\"\n                - Always\n                - Never\n                - IfNotPresent\n                type: string\n              imagePullSecrets:\n                description: |-\n                  An optional list of references to Secrets in the same namespace\n                  to use for pulling images from registries.\n                  See http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod\n                items:\n                  description: |-\n                    LocalObjectReference contains enough information to let you locate the\n                    referenced object inside the same namespace.\n                  properties:\n                    name:\n                      default: \"\"\n                      description: |-\n                        Name of the referent.\n                        This field is effectively required, but due to backwards compatibility is\n                        allowed to be empty. Instances of this type with an empty value here are\n                        almost certainly wrong.\n                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                      type: string\n                  type: object\n                  x-kubernetes-map-type: atomic\n                type: array\n              initContainers:\n                description: |-\n                  InitContainers allows injecting initContainers to the Pod definition. Those\n                  can be used to e.g.  fetch secrets for injection into the Prometheus\n                  configuration from external sources. Any errors during the execution of\n                  an initContainer will lead to a restart of the Pod. More info:\n                  https://kubernetes.io/docs/concepts/workloads/pods/init-containers/\n                  InitContainers described here modify an operator generated init\n                  containers if they share the same name and modifications are done via a\n                  strategic merge patch.\n\n                  The names of init container name managed by the operator are:\n                  * `init-config-reloader`.\n\n                  Overriding init containers is entirely outside the scope of what the\n                  maintainers will support and by doing so, you accept that this behaviour\n                  may break at any time without notice.\n                items:\n                  description: A single application container that you want to run within a pod.\n                  properties:\n                    args:\n                      description: |-\n                        Arguments to the entrypoint.\n                        The container image's CMD is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    command:\n                      description: |-\n                        Entrypoint array. Not executed within a shell.\n                        The container image's ENTRYPOINT is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    env:\n                      description: |-\n                        List of environment variables to set in the container.\n                        Cannot be updated.\n                      items:\n                        description: EnvVar represents an environment variable present in a Container.\n                        properties:\n                          name:\n                            description: Name of the environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          value:\n                            description: |-\n                              Variable references $(VAR_NAME) are expanded\n                              using the previously defined environment variables in the container and\n                              any service environment variables. If a variable cannot be resolved,\n                              the reference in the input string will be unchanged. Double $$ are reduced\n                              to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.\n                              \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\".\n                              Escaped references will never be expanded, regardless of whether the variable\n                              exists or not.\n                              Defaults to \"\".\n                            type: string\n                          valueFrom:\n                            description: Source for the environment variable's value. Cannot be used if value is not empty.\n                            properties:\n                              configMapKeyRef:\n                                description: Selects a key of a ConfigMap.\n                                properties:\n                                  key:\n                                    description: The key to select.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the ConfigMap or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              fieldRef:\n                                description: |-\n                                  Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,\n                                  spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.\n                                properties:\n                                  apiVersion:\n                                    description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                    type: string\n                                  fieldPath:\n                                    description: Path of the field to select in the specified API version.\n                                    type: string\n                                required:\n                                - fieldPath\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              resourceFieldRef:\n                                description: |-\n                                  Selects a resource of the container: only resources limits and requests\n                                  (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.\n                                properties:\n                                  containerName:\n                                    description: 'Container name: required for volumes, optional for env vars'\n                                    type: string\n                                  divisor:\n                                    anyOf:\n                                    - type: integer\n                                    - type: string\n                                    description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                    x-kubernetes-int-or-string: true\n                                  resource:\n                                    description: 'Required: resource to select'\n                                    type: string\n                                required:\n                                - resource\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              secretKeyRef:\n                                description: Selects a key of a secret in the pod's namespace\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            type: object\n                        required:\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - name\n                      x-kubernetes-list-type: map\n                    envFrom:\n                      description: |-\n                        List of sources to populate environment variables in the container.\n                        The keys defined within a source must be a C_IDENTIFIER. All invalid keys\n                        will be reported as an event when the container is starting. When a key exists in multiple\n                        sources, the value associated with the last source will take precedence.\n                        Values defined by an Env with a duplicate key will take precedence.\n                        Cannot be updated.\n                      items:\n                        description: EnvFromSource represents the source of a set of ConfigMaps or Secrets\n                        properties:\n                          configMapRef:\n                            description: The ConfigMap to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          prefix:\n                            description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          secretRef:\n                            description: The Secret to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    image:\n                      description: |-\n                        Container image name.\n                        More info: https://kubernetes.io/docs/concepts/containers/images\n                        This field is optional to allow higher level config management to default or override\n                        container images in workload controllers like Deployments and StatefulSets.\n                      type: string\n                    imagePullPolicy:\n                      description: |-\n                        Image pull policy.\n                        One of Always, Never, IfNotPresent.\n                        Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/containers/images#updating-images\n                      type: string\n                    lifecycle:\n                      description: |-\n                        Actions that the management system should take in response to container lifecycle events.\n                        Cannot be updated.\n                      properties:\n                        postStart:\n                          description: |-\n                            PostStart is called immediately after a container is created. If the handler fails,\n                            the container is terminated and restarted according to its restart policy.\n                            Other management of the container blocks until the hook completes.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        preStop:\n                          description: |-\n                            PreStop is called immediately before a container is terminated due to an\n                            API request or management event such as liveness/startup probe failure,\n                            preemption, resource contention, etc. The handler is not called if the\n                            container crashes or exits. The Pod's termination grace period countdown begins before the\n                            PreStop hook is executed. Regardless of the outcome of the handler, the\n                            container will eventually terminate within the Pod's termination grace\n                            period (unless delayed by finalizers). Other management of the container blocks until the hook completes\n                            or until the termination grace period is reached.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        stopSignal:\n                          description: |-\n                            StopSignal defines which signal will be sent to a container when it is being stopped.\n                            If not specified, the default is defined by the container runtime in use.\n                            StopSignal can only be set for Pods with a non-empty .spec.os.name\n                          type: string\n                      type: object\n                    livenessProbe:\n                      description: |-\n                        Periodic probe of container liveness.\n                        Container will be restarted if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    name:\n                      description: |-\n                        Name of the container specified as a DNS_LABEL.\n                        Each container in a pod must have a unique name (DNS_LABEL).\n                        Cannot be updated.\n                      type: string\n                    ports:\n                      description: |-\n                        List of ports to expose from the container. Not specifying a port here\n                        DOES NOT prevent that port from being exposed. Any port which is\n                        listening on the default \"0.0.0.0\" address inside a container will be\n                        accessible from the network.\n                        Modifying this array with strategic merge patch may corrupt the data.\n                        For more information See https://github.com/kubernetes/kubernetes/issues/108255.\n                        Cannot be updated.\n                      items:\n                        description: ContainerPort represents a network port in a single container.\n                        properties:\n                          containerPort:\n                            description: |-\n                              Number of port to expose on the pod's IP address.\n                              This must be a valid port number, 0 < x < 65536.\n                            format: int32\n                            type: integer\n                          hostIP:\n                            description: What host IP to bind the external port to.\n                            type: string\n                          hostPort:\n                            description: |-\n                              Number of port to expose on the host.\n                              If specified, this must be a valid port number, 0 < x < 65536.\n                              If HostNetwork is specified, this must match ContainerPort.\n                              Most containers do not need this.\n                            format: int32\n                            type: integer\n                          name:\n                            description: |-\n                              If specified, this must be an IANA_SVC_NAME and unique within the pod. Each\n                              named port in a pod must have a unique name. Name for the port that can be\n                              referred to by services.\n                            type: string\n                          protocol:\n                            default: TCP\n                            description: |-\n                              Protocol for port. Must be UDP, TCP, or SCTP.\n                              Defaults to \"TCP\".\n                            type: string\n                        required:\n                        - containerPort\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - containerPort\n                      - protocol\n                      x-kubernetes-list-type: map\n                    readinessProbe:\n                      description: |-\n                        Periodic probe of container service readiness.\n                        Container will be removed from service endpoints if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    resizePolicy:\n                      description: Resources resize policy for the container.\n                      items:\n                        description: ContainerResizePolicy represents resource resize policy for the container.\n                        properties:\n                          resourceName:\n                            description: |-\n                              Name of the resource to which this resource resize policy applies.\n                              Supported values: cpu, memory.\n                            type: string\n                          restartPolicy:\n                            description: |-\n                              Restart policy to apply when specified resource is resized.\n                              If not specified, it defaults to NotRequired.\n                            type: string\n                        required:\n                        - resourceName\n                        - restartPolicy\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    resources:\n                      description: |-\n                        Compute Resources required by this container.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                      properties:\n                        claims:\n                          description: |-\n                            Claims lists the names of resources, defined in spec.resourceClaims,\n                            that are used by this container.\n\n                            This is an alpha field and requires enabling the\n                            DynamicResourceAllocation feature gate.\n\n                            This field is immutable. It can only be set for containers.\n                          items:\n                            description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                            properties:\n                              name:\n                                description: |-\n                                  Name must match the name of one entry in pod.spec.resourceClaims of\n                                  the Pod where this field is used. It makes that resource available\n                                  inside a container.\n                                type: string\n                              request:\n                                description: |-\n                                  Request is the name chosen for a request in the referenced claim.\n                                  If empty, everything from the claim is made available, otherwise\n                                  only the result of this request.\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          type: array\n                          x-kubernetes-list-map-keys:\n                          - name\n                          x-kubernetes-list-type: map\n                        limits:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Limits describes the maximum amount of compute resources allowed.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                        requests:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Requests describes the minimum amount of compute resources required.\n                            If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                            otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                      type: object\n                    restartPolicy:\n                      description: |-\n                        RestartPolicy defines the restart behavior of individual containers in a pod.\n                        This field may only be set for init containers, and the only allowed value is \"Always\".\n                        For non-init containers or when this field is not specified,\n                        the restart behavior is defined by the Pod's restart policy and the container type.\n                        Setting the RestartPolicy as \"Always\" for the init container will have the following effect:\n                        this init container will be continually restarted on\n                        exit until all regular containers have terminated. Once all regular\n                        containers have completed, all init containers with restartPolicy \"Always\"\n                        will be shut down. This lifecycle differs from normal init containers and\n                        is often referred to as a \"sidecar\" container. Although this init\n                        container still starts in the init container sequence, it does not wait\n                        for the container to complete before proceeding to the next init\n                        container. Instead, the next init container starts immediately after this\n                        init container is started, or after any startupProbe has successfully\n                        completed.\n                      type: string\n                    securityContext:\n                      description: |-\n                        SecurityContext defines the security options the container should be run with.\n                        If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.\n                        More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/\n                      properties:\n                        allowPrivilegeEscalation:\n                          description: |-\n                            AllowPrivilegeEscalation controls whether a process can gain more\n                            privileges than its parent process. This bool directly controls if\n                            the no_new_privs flag will be set on the container process.\n                            AllowPrivilegeEscalation is true always when the container is:\n                            1) run as Privileged\n                            2) has CAP_SYS_ADMIN\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        appArmorProfile:\n                          description: |-\n                            appArmorProfile is the AppArmor options to use by this container. If set, this profile\n                            overrides the pod's appArmorProfile.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile loaded on the node that should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must match the loaded name of the profile.\n                                Must be set if and only if type is \"Localhost\".\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of AppArmor profile will be applied.\n                                Valid options are:\n                                  Localhost - a profile pre-loaded on the node.\n                                  RuntimeDefault - the container runtime's default profile.\n                                  Unconfined - no AppArmor enforcement.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        capabilities:\n                          description: |-\n                            The capabilities to add/drop when running containers.\n                            Defaults to the default set of capabilities granted by the container runtime.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            add:\n                              description: Added capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            drop:\n                              description: Removed capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        privileged:\n                          description: |-\n                            Run container in privileged mode.\n                            Processes in privileged containers are essentially equivalent to root on the host.\n                            Defaults to false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        procMount:\n                          description: |-\n                            procMount denotes the type of proc mount to use for the containers.\n                            The default value is Default which uses the container runtime defaults for\n                            readonly paths and masked paths.\n                            This requires the ProcMountType feature flag to be enabled.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: string\n                        readOnlyRootFilesystem:\n                          description: |-\n                            Whether this container has a read-only root filesystem.\n                            Default is false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        runAsGroup:\n                          description: |-\n                            The GID to run the entrypoint of the container process.\n                            Uses runtime default if unset.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        runAsNonRoot:\n                          description: |-\n                            Indicates that the container must run as a non-root user.\n                            If true, the Kubelet will validate the image at runtime to ensure that it\n                            does not run as UID 0 (root) and fail to start the container if it does.\n                            If unset or false, no such validation will be performed.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                          type: boolean\n                        runAsUser:\n                          description: |-\n                            The UID to run the entrypoint of the container process.\n                            Defaults to user specified in image metadata if unspecified.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        seLinuxOptions:\n                          description: |-\n                            The SELinux context to be applied to the container.\n                            If unspecified, the container runtime will allocate a random SELinux context for each\n                            container.  May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            level:\n                              description: Level is SELinux level label that applies to the container.\n                              type: string\n                            role:\n                              description: Role is a SELinux role label that applies to the container.\n                              type: string\n                            type:\n                              description: Type is a SELinux type label that applies to the container.\n                              type: string\n                            user:\n                              description: User is a SELinux user label that applies to the container.\n                              type: string\n                          type: object\n                        seccompProfile:\n                          description: |-\n                            The seccomp options to use by this container. If seccomp options are\n                            provided at both the pod & container level, the container options\n                            override the pod options.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile defined in a file on the node should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must be a descending path, relative to the kubelet's configured seccomp profile location.\n                                Must be set if type is \"Localhost\". Must NOT be set for any other type.\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of seccomp profile will be applied.\n                                Valid options are:\n\n                                Localhost - a profile defined in a file on the node should be used.\n                                RuntimeDefault - the container runtime default profile should be used.\n                                Unconfined - no profile should be applied.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        windowsOptions:\n                          description: |-\n                            The Windows specific settings applied to all containers.\n                            If unspecified, the options from the PodSecurityContext will be used.\n                            If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is linux.\n                          properties:\n                            gmsaCredentialSpec:\n                              description: |-\n                                GMSACredentialSpec is where the GMSA admission webhook\n                                (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the\n                                GMSA credential spec named by the GMSACredentialSpecName field.\n                              type: string\n                            gmsaCredentialSpecName:\n                              description: GMSACredentialSpecName is the name of the GMSA credential spec to use.\n                              type: string\n                            hostProcess:\n                              description: |-\n                                HostProcess determines if a container should be run as a 'Host Process' container.\n                                All of a Pod's containers must have the same effective HostProcess value\n                                (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).\n                                In addition, if HostProcess is true then HostNetwork must also be set to true.\n                              type: boolean\n                            runAsUserName:\n                              description: |-\n                                The UserName in Windows to run the entrypoint of the container process.\n                                Defaults to the user specified in image metadata if unspecified.\n                                May also be set in PodSecurityContext. If set in both SecurityContext and\n                                PodSecurityContext, the value specified in SecurityContext takes precedence.\n                              type: string\n                          type: object\n                      type: object\n                    startupProbe:\n                      description: |-\n                        StartupProbe indicates that the Pod has successfully initialized.\n                        If specified, no other probes are executed until this completes successfully.\n                        If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.\n                        This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,\n                        when it might take a long time to load data or warm a cache, than during steady-state operation.\n                        This cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    stdin:\n                      description: |-\n                        Whether this container should allocate a buffer for stdin in the container runtime. If this\n                        is not set, reads from stdin in the container will always result in EOF.\n                        Default is false.\n                      type: boolean\n                    stdinOnce:\n                      description: |-\n                        Whether the container runtime should close the stdin channel after it has been opened by\n                        a single attach. When stdin is true the stdin stream will remain open across multiple attach\n                        sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the\n                        first client attaches to stdin, and then remains open and accepts data until the client disconnects,\n                        at which time stdin is closed and remains closed until the container is restarted. If this\n                        flag is false, a container processes that reads from stdin will never receive an EOF.\n                        Default is false\n                      type: boolean\n                    terminationMessagePath:\n                      description: |-\n                        Optional: Path at which the file to which the container's termination message\n                        will be written is mounted into the container's filesystem.\n                        Message written is intended to be brief final status, such as an assertion failure message.\n                        Will be truncated by the node if greater than 4096 bytes. The total message length across\n                        all containers will be limited to 12kb.\n                        Defaults to /dev/termination-log.\n                        Cannot be updated.\n                      type: string\n                    terminationMessagePolicy:\n                      description: |-\n                        Indicate how the termination message should be populated. File will use the contents of\n                        terminationMessagePath to populate the container status message on both success and failure.\n                        FallbackToLogsOnError will use the last chunk of container log output if the termination\n                        message file is empty and the container exited with an error.\n                        The log output is limited to 2048 bytes or 80 lines, whichever is smaller.\n                        Defaults to File.\n                        Cannot be updated.\n                      type: string\n                    tty:\n                      description: |-\n                        Whether this container should allocate a TTY for itself, also requires 'stdin' to be true.\n                        Default is false.\n                      type: boolean\n                    volumeDevices:\n                      description: volumeDevices is the list of block devices to be used by the container.\n                      items:\n                        description: volumeDevice describes a mapping of a raw block device within a container.\n                        properties:\n                          devicePath:\n                            description: devicePath is the path inside of the container that the device will be mapped to.\n                            type: string\n                          name:\n                            description: name must match the name of a persistentVolumeClaim in the pod\n                            type: string\n                        required:\n                        - devicePath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - devicePath\n                      x-kubernetes-list-type: map\n                    volumeMounts:\n                      description: |-\n                        Pod volumes to mount into the container's filesystem.\n                        Cannot be updated.\n                      items:\n                        description: VolumeMount describes a mounting of a Volume within a container.\n                        properties:\n                          mountPath:\n                            description: |-\n                              Path within the container at which the volume should be mounted.  Must\n                              not contain ':'.\n                            type: string\n                          mountPropagation:\n                            description: |-\n                              mountPropagation determines how mounts are propagated from the host\n                              to container and the other way around.\n                              When not set, MountPropagationNone is used.\n                              This field is beta in 1.10.\n                              When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                              (which defaults to None).\n                            type: string\n                          name:\n                            description: This must match the Name of a Volume.\n                            type: string\n                          readOnly:\n                            description: |-\n                              Mounted read-only if true, read-write otherwise (false or unspecified).\n                              Defaults to false.\n                            type: boolean\n                          recursiveReadOnly:\n                            description: |-\n                              RecursiveReadOnly specifies whether read-only mounts should be handled\n                              recursively.\n\n                              If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                              If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                              recursively read-only.  If this field is set to IfPossible, the mount is made\n                              recursively read-only, if it is supported by the container runtime.  If this\n                              field is set to Enabled, the mount is made recursively read-only if it is\n                              supported by the container runtime, otherwise the pod will not be started and\n                              an error will be generated to indicate the reason.\n\n                              If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                              None (or be unspecified, which defaults to None).\n\n                              If this field is not specified, it is treated as an equivalent of Disabled.\n                            type: string\n                          subPath:\n                            description: |-\n                              Path within the volume from which the container's volume should be mounted.\n                              Defaults to \"\" (volume's root).\n                            type: string\n                          subPathExpr:\n                            description: |-\n                              Expanded path within the volume from which the container's volume should be mounted.\n                              Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                              Defaults to \"\" (volume's root).\n                              SubPathExpr and SubPath are mutually exclusive.\n                            type: string\n                        required:\n                        - mountPath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - mountPath\n                      x-kubernetes-list-type: map\n                    workingDir:\n                      description: |-\n                        Container's working directory.\n                        If not specified, the container runtime's default will be used, which\n                        might be configured in the container image.\n                        Cannot be updated.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                type: array\n              keepDroppedTargets:\n                description: |-\n                  Per-scrape limit on the number of targets dropped by relabeling\n                  that will be kept in memory. 0 means no limit.\n\n                  It requires Prometheus >= v2.47.0.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedKeepDroppedTargets.\n                format: int64\n                type: integer\n              labelLimit:\n                description: |-\n                  Per-scrape limit on number of labels that will be accepted for a sample.\n                  Only valid in Prometheus versions 2.45.0 and newer.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedLabelLimit.\n                format: int64\n                type: integer\n              labelNameLengthLimit:\n                description: |-\n                  Per-scrape limit on length of labels name that will be accepted for a sample.\n                  Only valid in Prometheus versions 2.45.0 and newer.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedLabelNameLengthLimit.\n                format: int64\n                type: integer\n              labelValueLengthLimit:\n                description: |-\n                  Per-scrape limit on length of labels value that will be accepted for a sample.\n                  Only valid in Prometheus versions 2.45.0 and newer.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedLabelValueLengthLimit.\n                format: int64\n                type: integer\n              listenLocal:\n                description: |-\n                  When true, the Prometheus server listens on the loopback address\n                  instead of the Pod IP's address.\n                type: boolean\n              logFormat:\n                description: Log format for Log level for Prometheus and the config-reloader sidecar.\n                enum:\n                - \"\"\n                - logfmt\n                - json\n                type: string\n              logLevel:\n                description: Log level for Prometheus and the config-reloader sidecar.\n                enum:\n                - \"\"\n                - debug\n                - info\n                - warn\n                - error\n                type: string\n              maximumStartupDurationSeconds:\n                description: |-\n                  Defines the maximum time that the `prometheus` container's startup probe will wait before being considered failed. The startup probe will return success after the WAL replay is complete.\n                  If set, the value should be greater than 60 (seconds). Otherwise it will be equal to 600 seconds (15 minutes).\n                format: int32\n                minimum: 60\n                type: integer\n              minReadySeconds:\n                description: |-\n                  Minimum number of seconds for which a newly created Pod should be ready\n                  without any of its container crashing for it to be considered available.\n\n                  If unset, pods will be considered available as soon as they are ready.\n                format: int32\n                minimum: 0\n                type: integer\n              mode:\n                description: |-\n                  Mode defines how the Prometheus operator deploys the PrometheusAgent pod(s).\n\n                  (Alpha) Using this field requires the `PrometheusAgentDaemonSet` feature gate to be enabled.\n                enum:\n                - StatefulSet\n                - DaemonSet\n                type: string\n              nameEscapingScheme:\n                description: |-\n                  Specifies the character escaping scheme that will be requested when scraping\n                  for metric and label names that do not conform to the legacy Prometheus\n                  character set.\n\n                  It requires Prometheus >= v3.4.0.\n                enum:\n                - AllowUTF8\n                - Underscores\n                - Dots\n                - Values\n                type: string\n              nameValidationScheme:\n                description: |-\n                  Specifies the validation scheme for metric and label names.\n\n                  It requires Prometheus >= v2.55.0.\n                enum:\n                - UTF8\n                - Legacy\n                type: string\n              nodeSelector:\n                additionalProperties:\n                  type: string\n                description: Defines on which Nodes the Pods are scheduled.\n                type: object\n              otlp:\n                description: |-\n                  Settings related to the OTLP receiver feature.\n                  It requires Prometheus >= v2.55.0.\n                properties:\n                  convertHistogramsToNHCB:\n                    description: |-\n                      Configures optional translation of OTLP explicit bucket histograms into native histograms with custom buckets.\n                      It requires Prometheus >= v3.4.0.\n                    type: boolean\n                  ignoreResourceAttributes:\n                    description: |-\n                      List of OpenTelemetry resource attributes to ignore when `promoteAllResourceAttributes` is true.\n\n                      It requires `promoteAllResourceAttributes` to be true.\n                      It requires Prometheus >= v3.5.0.\n                    items:\n                      minLength: 1\n                      type: string\n                    minItems: 1\n                    type: array\n                    x-kubernetes-list-type: set\n                  keepIdentifyingResourceAttributes:\n                    description: |-\n                      Enables adding `service.name`, `service.namespace` and `service.instance.id`\n                      resource attributes to the `target_info` metric, on top of converting them into the `instance` and `job` labels.\n\n                      It requires Prometheus >= v3.1.0.\n                    type: boolean\n                  promoteAllResourceAttributes:\n                    description: |-\n                      Promote all resource attributes to metric labels except the ones defined in `ignoreResourceAttributes`.\n\n                      Cannot be true when `promoteResourceAttributes` is defined.\n                      It requires Prometheus >= v3.5.0.\n                    type: boolean\n                  promoteResourceAttributes:\n                    description: |-\n                      List of OpenTelemetry Attributes that should be promoted to metric labels, defaults to none.\n                      Cannot be defined when `promoteAllResourceAttributes` is true.\n                    items:\n                      minLength: 1\n                      type: string\n                    minItems: 1\n                    type: array\n                    x-kubernetes-list-type: set\n                  translationStrategy:\n                    description: |-\n                      Configures how the OTLP receiver endpoint translates the incoming metrics.\n\n                      It requires Prometheus >= v3.0.0.\n                    enum:\n                    - NoUTF8EscapingWithSuffixes\n                    - UnderscoreEscapingWithSuffixes\n                    - NoTranslation\n                    type: string\n                type: object\n              overrideHonorLabels:\n                description: |-\n                  When true, Prometheus resolves label conflicts by renaming the labels in the scraped data\n                   to “exported_” for all targets created from ServiceMonitor, PodMonitor and\n                  ScrapeConfig objects. Otherwise the HonorLabels field of the service or pod monitor applies.\n                  In practice,`overrideHonorLaels:true` enforces `honorLabels:false`\n                  for all ServiceMonitor, PodMonitor and ScrapeConfig objects.\n                type: boolean\n              overrideHonorTimestamps:\n                description: |-\n                  When true, Prometheus ignores the timestamps for all the targets created\n                  from service and pod monitors.\n                  Otherwise the HonorTimestamps field of the service or pod monitor applies.\n                type: boolean\n              paused:\n                description: |-\n                  When a Prometheus deployment is paused, no actions except for deletion\n                  will be performed on the underlying objects.\n                type: boolean\n              persistentVolumeClaimRetentionPolicy:\n                description: |-\n                  The field controls if and how PVCs are deleted during the lifecycle of a StatefulSet.\n                  The default behavior is all PVCs are retained.\n                  This is an alpha field from kubernetes 1.23 until 1.26 and a beta field from 1.26.\n                  It requires enabling the StatefulSetAutoDeletePVC feature gate.\n                properties:\n                  whenDeleted:\n                    description: |-\n                      WhenDeleted specifies what happens to PVCs created from StatefulSet\n                      VolumeClaimTemplates when the StatefulSet is deleted. The default policy\n                      of `Retain` causes PVCs to not be affected by StatefulSet deletion. The\n                      `Delete` policy causes those PVCs to be deleted.\n                    type: string\n                  whenScaled:\n                    description: |-\n                      WhenScaled specifies what happens to PVCs created from StatefulSet\n                      VolumeClaimTemplates when the StatefulSet is scaled down. The default\n                      policy of `Retain` causes PVCs to not be affected by a scaledown. The\n                      `Delete` policy causes the associated PVCs for any excess pods above\n                      the replica count to be deleted.\n                    type: string\n                type: object\n              podMetadata:\n                description: |-\n                  PodMetadata configures labels and annotations which are propagated to the Prometheus pods.\n\n                  The following items are reserved and cannot be overridden:\n                  * \"prometheus\" label, set to the name of the Prometheus object.\n                  * \"app.kubernetes.io/instance\" label, set to the name of the Prometheus object.\n                  * \"app.kubernetes.io/managed-by\" label, set to \"prometheus-operator\".\n                  * \"app.kubernetes.io/name\" label, set to \"prometheus\".\n                  * \"app.kubernetes.io/version\" label, set to the Prometheus version.\n                  * \"operator.prometheus.io/name\" label, set to the name of the Prometheus object.\n                  * \"operator.prometheus.io/shard\" label, set to the shard number of the Prometheus object.\n                  * \"kubectl.kubernetes.io/default-container\" annotation, set to \"prometheus\".\n                properties:\n                  annotations:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      Annotations is an unstructured key value map stored with a resource that may be\n                      set by external tools to store and retrieve arbitrary metadata. They are not\n                      queryable and should be preserved when modifying objects.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/\n                    type: object\n                  labels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      Map of string keys and values that can be used to organize and categorize\n                      (scope and select) objects. May match selectors of replication controllers\n                      and services.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/\n                    type: object\n                  name:\n                    description: |-\n                      Name must be unique within a namespace. Is required when creating resources, although\n                      some resources may allow a client to request the generation of an appropriate name\n                      automatically. Name is primarily intended for creation idempotence and configuration\n                      definition.\n                      Cannot be updated.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\n                    type: string\n                type: object\n              podMonitorNamespaceSelector:\n                description: |-\n                  Namespaces to match for PodMonitors discovery. An empty label selector\n                  matches all namespaces. A null label selector (default value) matches the current\n                  namespace only.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              podMonitorSelector:\n                description: |-\n                  PodMonitors to be selected for target discovery. An empty label selector\n                  matches all objects. A null label selector matches no objects.\n\n                  If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector`\n                  and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged.\n                  The Prometheus operator will ensure that the Prometheus configuration's\n                  Secret exists, but it is the responsibility of the user to provide the raw\n                  gzipped Prometheus configuration under the `prometheus.yaml.gz` key.\n                  This behavior is *deprecated* and will be removed in the next major version\n                  of the custom resource definition. It is recommended to use\n                  `spec.additionalScrapeConfigs` instead.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              podTargetLabels:\n                description: |-\n                  PodTargetLabels are appended to the `spec.podTargetLabels` field of all\n                  PodMonitor and ServiceMonitor objects.\n                items:\n                  type: string\n                type: array\n              portName:\n                default: web\n                description: |-\n                  Port name used for the pods and governing service.\n                  Default: \"web\"\n                type: string\n              priorityClassName:\n                description: Priority class assigned to the Pods.\n                type: string\n              probeNamespaceSelector:\n                description: |-\n                  Namespaces to match for Probe discovery. An empty label\n                  selector matches all namespaces. A null label selector matches the\n                  current namespace only.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              probeSelector:\n                description: |-\n                  Probes to be selected for target discovery. An empty label selector\n                  matches all objects. A null label selector matches no objects.\n\n                  If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector`\n                  and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged.\n                  The Prometheus operator will ensure that the Prometheus configuration's\n                  Secret exists, but it is the responsibility of the user to provide the raw\n                  gzipped Prometheus configuration under the `prometheus.yaml.gz` key.\n                  This behavior is *deprecated* and will be removed in the next major version\n                  of the custom resource definition. It is recommended to use\n                  `spec.additionalScrapeConfigs` instead.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              prometheusExternalLabelName:\n                description: |-\n                  Name of Prometheus external label used to denote the Prometheus instance\n                  name. The external label will _not_ be added when the field is set to\n                  the empty string (`\"\"`).\n\n                  Default: \"prometheus\"\n                type: string\n              reloadStrategy:\n                description: |-\n                  Defines the strategy used to reload the Prometheus configuration.\n                  If not specified, the configuration is reloaded using the /-/reload HTTP endpoint.\n                enum:\n                - HTTP\n                - ProcessSignal\n                type: string\n              remoteWrite:\n                description: Defines the list of remote write configurations.\n                items:\n                  description: |-\n                    RemoteWriteSpec defines the configuration to write samples from Prometheus\n                    to a remote endpoint.\n                  properties:\n                    authorization:\n                      description: |-\n                        Authorization section for the URL.\n\n                        It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0.\n\n                        Cannot be set at the same time as `sigv4`, `basicAuth`, `oauth2`, or `azureAd`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        credentialsFile:\n                          description: File to read a secret from, mutually exclusive with `credentials`.\n                          type: string\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    azureAd:\n                      description: |-\n                        AzureAD for the URL.\n\n                        It requires Prometheus >= v2.45.0 or Thanos >= v0.31.0.\n\n                        Cannot be set at the same time as `authorization`, `basicAuth`, `oauth2`, or `sigv4`.\n                      properties:\n                        cloud:\n                          description: The Azure Cloud. Options are 'AzurePublic', 'AzureChina', or 'AzureGovernment'.\n                          enum:\n                          - AzureChina\n                          - AzureGovernment\n                          - AzurePublic\n                          type: string\n                        managedIdentity:\n                          description: |-\n                            ManagedIdentity defines the Azure User-assigned Managed identity.\n                            Cannot be set at the same time as `oauth` or `sdk`.\n                          properties:\n                            clientId:\n                              description: The client id\n                              type: string\n                          required:\n                          - clientId\n                          type: object\n                        oauth:\n                          description: |-\n                            OAuth defines the oauth config that is being used to authenticate.\n                            Cannot be set at the same time as `managedIdentity` or `sdk`.\n\n                            It requires Prometheus >= v2.48.0 or Thanos >= v0.31.0.\n                          properties:\n                            clientId:\n                              description: '`clientID` is the clientId of the Azure Active Directory application that is being used to authenticate.'\n                              minLength: 1\n                              type: string\n                            clientSecret:\n                              description: '`clientSecret` specifies a key of a Secret containing the client secret of the Azure Active Directory application that is being used to authenticate.'\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            tenantId:\n                              description: '`tenantId` is the tenant ID of the Azure Active Directory application that is being used to authenticate.'\n                              minLength: 1\n                              pattern: ^[0-9a-zA-Z-.]+$\n                              type: string\n                          required:\n                          - clientId\n                          - clientSecret\n                          - tenantId\n                          type: object\n                        sdk:\n                          description: |-\n                            SDK defines the Azure SDK config that is being used to authenticate.\n                            See https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication\n                            Cannot be set at the same time as `oauth` or `managedIdentity`.\n\n                            It requires Prometheus >= v2.52.0 or Thanos >= v0.36.0.\n                          properties:\n                            tenantId:\n                              description: '`tenantId` is the tenant ID of the azure active directory application that is being used to authenticate.'\n                              pattern: ^[0-9a-zA-Z-.]+$\n                              type: string\n                          type: object\n                      type: object\n                    basicAuth:\n                      description: |-\n                        BasicAuth configuration for the URL.\n\n                        Cannot be set at the same time as `sigv4`, `authorization`, `oauth2`, or `azureAd`.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    bearerToken:\n                      description: |-\n                        *Warning: this field shouldn't be used because the token value appears\n                        in clear-text. Prefer using `authorization`.*\n\n                        Deprecated: this will be removed in a future release.\n                      type: string\n                    bearerTokenFile:\n                      description: |-\n                        File from which to read bearer token for the URL.\n\n                        Deprecated: this will be removed in a future release. Prefer using `authorization`.\n                      type: string\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: |-\n                        Configure whether HTTP requests follow HTTP 3xx redirects.\n\n                        It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0.\n                      type: boolean\n                    headers:\n                      additionalProperties:\n                        type: string\n                      description: |-\n                        Custom HTTP headers to be sent along with each remote write request.\n                        Be aware that headers that are set by Prometheus itself can't be overwritten.\n\n                        It requires Prometheus >= v2.25.0 or Thanos >= v0.24.0.\n                      type: object\n                    messageVersion:\n                      description: |-\n                        The Remote Write message's version to use when writing to the endpoint.\n\n                        `Version1.0` corresponds to the `prometheus.WriteRequest` protobuf message introduced in Remote Write 1.0.\n                        `Version2.0` corresponds to the `io.prometheus.write.v2.Request` protobuf message introduced in Remote Write 2.0.\n\n                        When `Version2.0` is selected, Prometheus will automatically be\n                        configured to append the metadata of scraped metrics to the WAL.\n\n                        Before setting this field, consult with your remote storage provider\n                        what message version it supports.\n\n                        It requires Prometheus >= v2.54.0 or Thanos >= v0.37.0.\n                      enum:\n                      - V1.0\n                      - V2.0\n                      type: string\n                    metadataConfig:\n                      description: MetadataConfig configures the sending of series metadata to the remote storage.\n                      properties:\n                        maxSamplesPerSend:\n                          description: |-\n                            MaxSamplesPerSend is the maximum number of metadata samples per send.\n\n                            It requires Prometheus >= v2.29.0.\n                          format: int32\n                          minimum: -1\n                          type: integer\n                        send:\n                          description: Defines whether metric metadata is sent to the remote storage or not.\n                          type: boolean\n                        sendInterval:\n                          description: Defines how frequently metric metadata is sent to the remote storage.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                      type: object\n                    name:\n                      description: |-\n                        The name of the remote write queue, it must be unique if specified. The\n                        name is used in metrics and logging in order to differentiate queues.\n\n                        It requires Prometheus >= v2.15.0 or Thanos >= 0.24.0.\n                      type: string\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        OAuth2 configuration for the URL.\n\n                        It requires Prometheus >= v2.27.0 or Thanos >= v0.24.0.\n\n                        Cannot be set at the same time as `sigv4`, `authorization`, `basicAuth`, or `azureAd`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    queueConfig:\n                      description: QueueConfig allows tuning of the remote write queue parameters.\n                      properties:\n                        batchSendDeadline:\n                          description: BatchSendDeadline is the maximum time a sample will wait in buffer.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                        capacity:\n                          description: |-\n                            Capacity is the number of samples to buffer per shard before we start\n                            dropping them.\n                          type: integer\n                        maxBackoff:\n                          description: MaxBackoff is the maximum retry delay.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                        maxRetries:\n                          description: MaxRetries is the maximum number of times to retry a batch on recoverable errors.\n                          type: integer\n                        maxSamplesPerSend:\n                          description: MaxSamplesPerSend is the maximum number of samples per send.\n                          type: integer\n                        maxShards:\n                          description: MaxShards is the maximum number of shards, i.e. amount of concurrency.\n                          type: integer\n                        minBackoff:\n                          description: MinBackoff is the initial retry delay. Gets doubled for every retry.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                        minShards:\n                          description: MinShards is the minimum number of shards, i.e. amount of concurrency.\n                          type: integer\n                        retryOnRateLimit:\n                          description: |-\n                            Retry upon receiving a 429 status code from the remote-write storage.\n\n                            This is an *experimental feature*, it may change in any upcoming release\n                            in a breaking way.\n                          type: boolean\n                        sampleAgeLimit:\n                          description: |-\n                            SampleAgeLimit drops samples older than the limit.\n                            It requires Prometheus >= v2.50.0 or Thanos >= v0.32.0.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                      type: object\n                    remoteTimeout:\n                      description: Timeout for requests to the remote write endpoint.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    roundRobinDNS:\n                      description: |-\n                        When enabled:\n                            - The remote-write mechanism will resolve the hostname via DNS.\n                            - It will randomly select one of the resolved IP addresses and connect to it.\n\n                        When disabled (default behavior):\n                            - The Go standard library will handle hostname resolution.\n                            - It will attempt connections to each resolved IP address sequentially.\n\n                        Note: The connection timeout applies to the entire resolution and connection process.\n                              If disabled, the timeout is distributed across all connection attempts.\n\n                        It requires Prometheus >= v3.1.0 or Thanos >= v0.38.0.\n                      type: boolean\n                    sendExemplars:\n                      description: |-\n                        Enables sending of exemplars over remote write. Note that\n                        exemplar-storage itself must be enabled using the `spec.enableFeatures`\n                        option for exemplars to be scraped in the first place.\n\n                        It requires Prometheus >= v2.27.0 or Thanos >= v0.24.0.\n                      type: boolean\n                    sendNativeHistograms:\n                      description: |-\n                        Enables sending of native histograms, also known as sparse histograms\n                        over remote write.\n\n                        It requires Prometheus >= v2.40.0 or Thanos >= v0.30.0.\n                      type: boolean\n                    sigv4:\n                      description: |-\n                        Sigv4 allows to configures AWS's Signature Verification 4 for the URL.\n\n                        It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0.\n\n                        Cannot be set at the same time as `authorization`, `basicAuth`, `oauth2`, or `azureAd`.\n                      properties:\n                        accessKey:\n                          description: |-\n                            AccessKey is the AWS API key. If not specified, the environment variable\n                            `AWS_ACCESS_KEY_ID` is used.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        profile:\n                          description: Profile is the named AWS profile used to authenticate.\n                          type: string\n                        region:\n                          description: Region is the AWS region. If blank, the region from the default credentials chain used.\n                          type: string\n                        roleArn:\n                          description: RoleArn is the named AWS profile used to authenticate.\n                          type: string\n                        secretKey:\n                          description: |-\n                            SecretKey is the AWS API secret. If not specified, the environment\n                            variable `AWS_SECRET_ACCESS_KEY` is used.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    tlsConfig:\n                      description: TLS Config to use for the URL.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        caFile:\n                          description: Path to the CA cert in the Prometheus container to use for the targets.\n                          type: string\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        certFile:\n                          description: Path to the client cert file in the Prometheus container for the targets.\n                          type: string\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keyFile:\n                          description: Path to the client key file in the Prometheus container for the targets.\n                          type: string\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                    url:\n                      description: The URL of the endpoint to send samples to.\n                      minLength: 1\n                      type: string\n                    writeRelabelConfigs:\n                      description: The list of remote write relabel configurations.\n                      items:\n                        description: |-\n                          RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                          scraped samples and remote write samples.\n\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        properties:\n                          action:\n                            default: replace\n                            description: |-\n                              Action to perform based on the regex matching.\n\n                              `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                              `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                              Default: \"Replace\"\n                            enum:\n                            - replace\n                            - Replace\n                            - keep\n                            - Keep\n                            - drop\n                            - Drop\n                            - hashmod\n                            - HashMod\n                            - labelmap\n                            - LabelMap\n                            - labeldrop\n                            - LabelDrop\n                            - labelkeep\n                            - LabelKeep\n                            - lowercase\n                            - Lowercase\n                            - uppercase\n                            - Uppercase\n                            - keepequal\n                            - KeepEqual\n                            - dropequal\n                            - DropEqual\n                            type: string\n                          modulus:\n                            description: |-\n                              Modulus to take of the hash of the source label values.\n\n                              Only applicable when the action is `HashMod`.\n                            format: int64\n                            type: integer\n                          regex:\n                            description: Regular expression against which the extracted value is matched.\n                            type: string\n                          replacement:\n                            description: |-\n                              Replacement value against which a Replace action is performed if the\n                              regular expression matches.\n\n                              Regex capture groups are available.\n                            type: string\n                          separator:\n                            description: Separator is the string between concatenated SourceLabels.\n                            type: string\n                          sourceLabels:\n                            description: |-\n                              The source labels select values from existing labels. Their content is\n                              concatenated using the configured Separator and matched against the\n                              configured regular expression.\n                            items:\n                              description: |-\n                                LabelName is a valid Prometheus label name which may only contain ASCII\n                                letters, numbers, as well as underscores.\n                              pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                              type: string\n                            type: array\n                          targetLabel:\n                            description: |-\n                              Label to which the resulting string is written in a replacement.\n\n                              It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                              `KeepEqual` and `DropEqual` actions.\n\n                              Regex capture groups are available.\n                            type: string\n                        type: object\n                      type: array\n                  required:\n                  - url\n                  type: object\n                type: array\n              remoteWriteReceiverMessageVersions:\n                description: |-\n                  List of the protobuf message versions to accept when receiving the\n                  remote writes.\n\n                  It requires Prometheus >= v2.54.0.\n                items:\n                  enum:\n                  - V1.0\n                  - V2.0\n                  type: string\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: set\n              replicaExternalLabelName:\n                description: |-\n                  Name of Prometheus external label used to denote the replica name.\n                  The external label will _not_ be added when the field is set to the\n                  empty string (`\"\"`).\n\n                  Default: \"prometheus_replica\"\n                type: string\n              replicas:\n                description: |-\n                  Number of replicas of each shard to deploy for a Prometheus deployment.\n                  `spec.replicas` multiplied by `spec.shards` is the total number of Pods\n                  created.\n\n                  Default: 1\n                format: int32\n                type: integer\n              resources:\n                description: Defines the resources requests and limits of the 'prometheus' container.\n                properties:\n                  claims:\n                    description: |-\n                      Claims lists the names of resources, defined in spec.resourceClaims,\n                      that are used by this container.\n\n                      This is an alpha field and requires enabling the\n                      DynamicResourceAllocation feature gate.\n\n                      This field is immutable. It can only be set for containers.\n                    items:\n                      description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                      properties:\n                        name:\n                          description: |-\n                            Name must match the name of one entry in pod.spec.resourceClaims of\n                            the Pod where this field is used. It makes that resource available\n                            inside a container.\n                          type: string\n                        request:\n                          description: |-\n                            Request is the name chosen for a request in the referenced claim.\n                            If empty, everything from the claim is made available, otherwise\n                            only the result of this request.\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    type: array\n                    x-kubernetes-list-map-keys:\n                    - name\n                    x-kubernetes-list-type: map\n                  limits:\n                    additionalProperties:\n                      anyOf:\n                      - type: integer\n                      - type: string\n                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                      x-kubernetes-int-or-string: true\n                    description: |-\n                      Limits describes the maximum amount of compute resources allowed.\n                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                    type: object\n                  requests:\n                    additionalProperties:\n                      anyOf:\n                      - type: integer\n                      - type: string\n                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                      x-kubernetes-int-or-string: true\n                    description: |-\n                      Requests describes the minimum amount of compute resources required.\n                      If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                      otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                    type: object\n                type: object\n              routePrefix:\n                description: |-\n                  The route prefix Prometheus registers HTTP handlers for.\n\n                  This is useful when using `spec.externalURL`, and a proxy is rewriting\n                  HTTP routes of a request, and the actual ExternalURL is still true, but\n                  the server serves requests under a different route prefix. For example\n                  for use with `kubectl proxy`.\n                type: string\n              runtime:\n                description: RuntimeConfig configures the values for the Prometheus process behavior\n                properties:\n                  goGC:\n                    description: |-\n                      The Go garbage collection target percentage. Lowering this number may increase the CPU usage.\n                      See: https://tip.golang.org/doc/gc-guide#GOGC\n                    format: int32\n                    minimum: -1\n                    type: integer\n                type: object\n              sampleLimit:\n                description: |-\n                  SampleLimit defines per-scrape limit on number of scraped samples that will be accepted.\n                  Only valid in Prometheus versions 2.45.0 and newer.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedSampleLimit.\n                format: int64\n                type: integer\n              scrapeClasses:\n                description: |-\n                  List of scrape classes to expose to scraping objects such as\n                  PodMonitors, ServiceMonitors, Probes and ScrapeConfigs.\n\n                  This is an *experimental feature*, it may change in any upcoming release\n                  in a breaking way.\n                items:\n                  properties:\n                    attachMetadata:\n                      description: |-\n                        AttachMetadata configures additional metadata to the discovered targets.\n                        When the scrape object defines its own configuration, it takes\n                        precedence over the scrape class configuration.\n                      properties:\n                        node:\n                          description: |-\n                            When set to true, Prometheus attaches node metadata to the discovered\n                            targets.\n\n                            The Prometheus service account must have the `list` and `watch`\n                            permissions on the `Nodes` objects.\n                          type: boolean\n                      type: object\n                    authorization:\n                      description: |-\n                        Authorization section for the ScrapeClass.\n                        It will only apply if the scrape resource doesn't specify any Authorization.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        credentialsFile:\n                          description: File to read a secret from, mutually exclusive with `credentials`.\n                          type: string\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    default:\n                      description: |-\n                        Default indicates that the scrape applies to all scrape objects that\n                        don't configure an explicit scrape class name.\n\n                        Only one scrape class can be set as the default.\n                      type: boolean\n                    fallbackScrapeProtocol:\n                      description: |-\n                        The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type.\n                        It will only apply if the scrape resource doesn't specify any FallbackScrapeProtocol\n\n                        It requires Prometheus >= v3.0.0.\n                      enum:\n                      - PrometheusProto\n                      - OpenMetricsText0.0.1\n                      - OpenMetricsText1.0.0\n                      - PrometheusText0.0.4\n                      - PrometheusText1.0.0\n                      type: string\n                    metricRelabelings:\n                      description: |-\n                        MetricRelabelings configures the relabeling rules to apply to all samples before ingestion.\n\n                        The Operator adds the scrape class metric relabelings defined here.\n                        Then the Operator adds the target-specific metric relabelings defined in ServiceMonitors, PodMonitors, Probes and ScrapeConfigs.\n                        Then the Operator adds namespace enforcement relabeling rule, specified in '.spec.enforcedNamespaceLabel'.\n\n                        More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs\n                      items:\n                        description: |-\n                          RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                          scraped samples and remote write samples.\n\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        properties:\n                          action:\n                            default: replace\n                            description: |-\n                              Action to perform based on the regex matching.\n\n                              `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                              `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                              Default: \"Replace\"\n                            enum:\n                            - replace\n                            - Replace\n                            - keep\n                            - Keep\n                            - drop\n                            - Drop\n                            - hashmod\n                            - HashMod\n                            - labelmap\n                            - LabelMap\n                            - labeldrop\n                            - LabelDrop\n                            - labelkeep\n                            - LabelKeep\n                            - lowercase\n                            - Lowercase\n                            - uppercase\n                            - Uppercase\n                            - keepequal\n                            - KeepEqual\n                            - dropequal\n                            - DropEqual\n                            type: string\n                          modulus:\n                            description: |-\n                              Modulus to take of the hash of the source label values.\n\n                              Only applicable when the action is `HashMod`.\n                            format: int64\n                            type: integer\n                          regex:\n                            description: Regular expression against which the extracted value is matched.\n                            type: string\n                          replacement:\n                            description: |-\n                              Replacement value against which a Replace action is performed if the\n                              regular expression matches.\n\n                              Regex capture groups are available.\n                            type: string\n                          separator:\n                            description: Separator is the string between concatenated SourceLabels.\n                            type: string\n                          sourceLabels:\n                            description: |-\n                              The source labels select values from existing labels. Their content is\n                              concatenated using the configured Separator and matched against the\n                              configured regular expression.\n                            items:\n                              description: |-\n                                LabelName is a valid Prometheus label name which may only contain ASCII\n                                letters, numbers, as well as underscores.\n                              pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                              type: string\n                            type: array\n                          targetLabel:\n                            description: |-\n                              Label to which the resulting string is written in a replacement.\n\n                              It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                              `KeepEqual` and `DropEqual` actions.\n\n                              Regex capture groups are available.\n                            type: string\n                        type: object\n                      type: array\n                    name:\n                      description: Name of the scrape class.\n                      minLength: 1\n                      type: string\n                    relabelings:\n                      description: |-\n                        Relabelings configures the relabeling rules to apply to all scrape targets.\n\n                        The Operator automatically adds relabelings for a few standard Kubernetes fields\n                        like `__meta_kubernetes_namespace` and `__meta_kubernetes_service_name`.\n                        Then the Operator adds the scrape class relabelings defined here.\n                        Then the Operator adds the target-specific relabelings defined in the scrape object.\n\n                        More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                      items:\n                        description: |-\n                          RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                          scraped samples and remote write samples.\n\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        properties:\n                          action:\n                            default: replace\n                            description: |-\n                              Action to perform based on the regex matching.\n\n                              `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                              `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                              Default: \"Replace\"\n                            enum:\n                            - replace\n                            - Replace\n                            - keep\n                            - Keep\n                            - drop\n                            - Drop\n                            - hashmod\n                            - HashMod\n                            - labelmap\n                            - LabelMap\n                            - labeldrop\n                            - LabelDrop\n                            - labelkeep\n                            - LabelKeep\n                            - lowercase\n                            - Lowercase\n                            - uppercase\n                            - Uppercase\n                            - keepequal\n                            - KeepEqual\n                            - dropequal\n                            - DropEqual\n                            type: string\n                          modulus:\n                            description: |-\n                              Modulus to take of the hash of the source label values.\n\n                              Only applicable when the action is `HashMod`.\n                            format: int64\n                            type: integer\n                          regex:\n                            description: Regular expression against which the extracted value is matched.\n                            type: string\n                          replacement:\n                            description: |-\n                              Replacement value against which a Replace action is performed if the\n                              regular expression matches.\n\n                              Regex capture groups are available.\n                            type: string\n                          separator:\n                            description: Separator is the string between concatenated SourceLabels.\n                            type: string\n                          sourceLabels:\n                            description: |-\n                              The source labels select values from existing labels. Their content is\n                              concatenated using the configured Separator and matched against the\n                              configured regular expression.\n                            items:\n                              description: |-\n                                LabelName is a valid Prometheus label name which may only contain ASCII\n                                letters, numbers, as well as underscores.\n                              pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                              type: string\n                            type: array\n                          targetLabel:\n                            description: |-\n                              Label to which the resulting string is written in a replacement.\n\n                              It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                              `KeepEqual` and `DropEqual` actions.\n\n                              Regex capture groups are available.\n                            type: string\n                        type: object\n                      type: array\n                    tlsConfig:\n                      description: |-\n                        TLSConfig defines the TLS settings to use for the scrape. When the\n                        scrape objects define their own CA, certificate and/or key, they take\n                        precedence over the corresponding scrape class fields.\n\n                        For now only the `caFile`, `certFile` and `keyFile` fields are supported.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        caFile:\n                          description: Path to the CA cert in the Prometheus container to use for the targets.\n                          type: string\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        certFile:\n                          description: Path to the client cert file in the Prometheus container for the targets.\n                          type: string\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keyFile:\n                          description: Path to the client key file in the Prometheus container for the targets.\n                          type: string\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  required:\n                  - name\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n              scrapeClassicHistograms:\n                description: |-\n                  Whether to scrape a classic histogram that is also exposed as a native histogram.\n\n                  Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration.\n\n                  It requires Prometheus >= v3.5.0.\n                type: boolean\n              scrapeConfigNamespaceSelector:\n                description: |-\n                  Namespaces to match for ScrapeConfig discovery. An empty label selector\n                  matches all namespaces. A null label selector matches the current\n                  namespace only.\n\n                  Note that the ScrapeConfig custom resource definition is currently at Alpha level.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              scrapeConfigSelector:\n                description: |-\n                  ScrapeConfigs to be selected for target discovery. An empty label\n                  selector matches all objects. A null label selector matches no objects.\n\n                  If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector`\n                  and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged.\n                  The Prometheus operator will ensure that the Prometheus configuration's\n                  Secret exists, but it is the responsibility of the user to provide the raw\n                  gzipped Prometheus configuration under the `prometheus.yaml.gz` key.\n                  This behavior is *deprecated* and will be removed in the next major version\n                  of the custom resource definition. It is recommended to use\n                  `spec.additionalScrapeConfigs` instead.\n\n                  Note that the ScrapeConfig custom resource definition is currently at Alpha level.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              scrapeFailureLogFile:\n                description: |-\n                  File to which scrape failures are logged.\n                  Reloading the configuration will reopen the file.\n\n                  If the filename has an empty path, e.g. 'file.log', The Prometheus Pods\n                  will mount the file into an emptyDir volume at `/var/log/prometheus`.\n                  If a full path is provided, e.g. '/var/log/prometheus/file.log', you\n                  must mount a volume in the specified directory and it must be writable.\n                  It requires Prometheus >= v2.55.0.\n                minLength: 1\n                type: string\n              scrapeInterval:\n                default: 30s\n                description: |-\n                  Interval between consecutive scrapes.\n\n                  Default: \"30s\"\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              scrapeProtocols:\n                description: |-\n                  The protocols to negotiate during a scrape. It tells clients the\n                  protocols supported by Prometheus in order of preference (from most to least preferred).\n\n                  If unset, Prometheus uses its default value.\n\n                  It requires Prometheus >= v2.49.0.\n\n                  `PrometheusText1.0.0` requires Prometheus >= v3.0.0.\n                items:\n                  description: |-\n                    ScrapeProtocol represents a protocol used by Prometheus for scraping metrics.\n                    Supported values are:\n                    * `OpenMetricsText0.0.1`\n                    * `OpenMetricsText1.0.0`\n                    * `PrometheusProto`\n                    * `PrometheusText0.0.4`\n                    * `PrometheusText1.0.0`\n                  enum:\n                  - PrometheusProto\n                  - OpenMetricsText0.0.1\n                  - OpenMetricsText1.0.0\n                  - PrometheusText0.0.4\n                  - PrometheusText1.0.0\n                  type: string\n                type: array\n                x-kubernetes-list-type: set\n              scrapeTimeout:\n                description: |-\n                  Number of seconds to wait until a scrape request times out.\n                  The value cannot be greater than the scrape interval otherwise the operator will reject the resource.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              secrets:\n                description: |-\n                  Secrets is a list of Secrets in the same namespace as the Prometheus\n                  object, which shall be mounted into the Prometheus Pods.\n                  Each Secret is added to the StatefulSet definition as a volume named `secret-<secret-name>`.\n                  The Secrets are mounted into /etc/prometheus/secrets/<secret-name> in the 'prometheus' container.\n                items:\n                  type: string\n                type: array\n                x-kubernetes-list-type: set\n              securityContext:\n                description: |-\n                  SecurityContext holds pod-level security attributes and common container settings.\n                  This defaults to the default PodSecurityContext.\n                properties:\n                  appArmorProfile:\n                    description: |-\n                      appArmorProfile is the AppArmor options to use by the containers in this pod.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    properties:\n                      localhostProfile:\n                        description: |-\n                          localhostProfile indicates a profile loaded on the node that should be used.\n                          The profile must be preconfigured on the node to work.\n                          Must match the loaded name of the profile.\n                          Must be set if and only if type is \"Localhost\".\n                        type: string\n                      type:\n                        description: |-\n                          type indicates which kind of AppArmor profile will be applied.\n                          Valid options are:\n                            Localhost - a profile pre-loaded on the node.\n                            RuntimeDefault - the container runtime's default profile.\n                            Unconfined - no AppArmor enforcement.\n                        type: string\n                    required:\n                    - type\n                    type: object\n                  fsGroup:\n                    description: |-\n                      A special supplemental group that applies to all containers in a pod.\n                      Some volume types allow the Kubelet to change the ownership of that volume\n                      to be owned by the pod:\n\n                      1. The owning GID will be the FSGroup\n                      2. The setgid bit is set (new files created in the volume will be owned by FSGroup)\n                      3. The permission bits are OR'd with rw-rw----\n\n                      If unset, the Kubelet will not modify the ownership and permissions of any volume.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    format: int64\n                    type: integer\n                  fsGroupChangePolicy:\n                    description: |-\n                      fsGroupChangePolicy defines behavior of changing ownership and permission of the volume\n                      before being exposed inside Pod. This field will only apply to\n                      volume types which support fsGroup based ownership(and permissions).\n                      It will have no effect on ephemeral volume types such as: secret, configmaps\n                      and emptydir.\n                      Valid values are \"OnRootMismatch\" and \"Always\". If not specified, \"Always\" is used.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    type: string\n                  runAsGroup:\n                    description: |-\n                      The GID to run the entrypoint of the container process.\n                      Uses runtime default if unset.\n                      May also be set in SecurityContext.  If set in both SecurityContext and\n                      PodSecurityContext, the value specified in SecurityContext takes precedence\n                      for that container.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    format: int64\n                    type: integer\n                  runAsNonRoot:\n                    description: |-\n                      Indicates that the container must run as a non-root user.\n                      If true, the Kubelet will validate the image at runtime to ensure that it\n                      does not run as UID 0 (root) and fail to start the container if it does.\n                      If unset or false, no such validation will be performed.\n                      May also be set in SecurityContext.  If set in both SecurityContext and\n                      PodSecurityContext, the value specified in SecurityContext takes precedence.\n                    type: boolean\n                  runAsUser:\n                    description: |-\n                      The UID to run the entrypoint of the container process.\n                      Defaults to user specified in image metadata if unspecified.\n                      May also be set in SecurityContext.  If set in both SecurityContext and\n                      PodSecurityContext, the value specified in SecurityContext takes precedence\n                      for that container.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    format: int64\n                    type: integer\n                  seLinuxChangePolicy:\n                    description: |-\n                      seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod.\n                      It has no effect on nodes that do not support SELinux or to volumes does not support SELinux.\n                      Valid values are \"MountOption\" and \"Recursive\".\n\n                      \"Recursive\" means relabeling of all files on all Pod volumes by the container runtime.\n                      This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.\n\n                      \"MountOption\" mounts all eligible Pod volumes with `-o context` mount option.\n                      This requires all Pods that share the same volume to use the same SELinux label.\n                      It is not possible to share the same volume among privileged and unprivileged Pods.\n                      Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes\n                      whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their\n                      CSIDriver instance. Other volumes are always re-labelled recursively.\n                      \"MountOption\" value is allowed only when SELinuxMount feature gate is enabled.\n\n                      If not specified and SELinuxMount feature gate is enabled, \"MountOption\" is used.\n                      If not specified and SELinuxMount feature gate is disabled, \"MountOption\" is used for ReadWriteOncePod volumes\n                      and \"Recursive\" for all other volumes.\n\n                      This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.\n\n                      All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    type: string\n                  seLinuxOptions:\n                    description: |-\n                      The SELinux context to be applied to all containers.\n                      If unspecified, the container runtime will allocate a random SELinux context for each\n                      container.  May also be set in SecurityContext.  If set in\n                      both SecurityContext and PodSecurityContext, the value specified in SecurityContext\n                      takes precedence for that container.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    properties:\n                      level:\n                        description: Level is SELinux level label that applies to the container.\n                        type: string\n                      role:\n                        description: Role is a SELinux role label that applies to the container.\n                        type: string\n                      type:\n                        description: Type is a SELinux type label that applies to the container.\n                        type: string\n                      user:\n                        description: User is a SELinux user label that applies to the container.\n                        type: string\n                    type: object\n                  seccompProfile:\n                    description: |-\n                      The seccomp options to use by the containers in this pod.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    properties:\n                      localhostProfile:\n                        description: |-\n                          localhostProfile indicates a profile defined in a file on the node should be used.\n                          The profile must be preconfigured on the node to work.\n                          Must be a descending path, relative to the kubelet's configured seccomp profile location.\n                          Must be set if type is \"Localhost\". Must NOT be set for any other type.\n                        type: string\n                      type:\n                        description: |-\n                          type indicates which kind of seccomp profile will be applied.\n                          Valid options are:\n\n                          Localhost - a profile defined in a file on the node should be used.\n                          RuntimeDefault - the container runtime default profile should be used.\n                          Unconfined - no profile should be applied.\n                        type: string\n                    required:\n                    - type\n                    type: object\n                  supplementalGroups:\n                    description: |-\n                      A list of groups applied to the first process run in each container, in\n                      addition to the container's primary GID and fsGroup (if specified).  If\n                      the SupplementalGroupsPolicy feature is enabled, the\n                      supplementalGroupsPolicy field determines whether these are in addition\n                      to or instead of any group memberships defined in the container image.\n                      If unspecified, no additional groups are added, though group memberships\n                      defined in the container image may still be used, depending on the\n                      supplementalGroupsPolicy field.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    items:\n                      format: int64\n                      type: integer\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  supplementalGroupsPolicy:\n                    description: |-\n                      Defines how supplemental groups of the first container processes are calculated.\n                      Valid values are \"Merge\" and \"Strict\". If not specified, \"Merge\" is used.\n                      (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled\n                      and the container runtime must implement support for this feature.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    type: string\n                  sysctls:\n                    description: |-\n                      Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported\n                      sysctls (by the container runtime) might fail to launch.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    items:\n                      description: Sysctl defines a kernel parameter to be set\n                      properties:\n                        name:\n                          description: Name of a property to set\n                          type: string\n                        value:\n                          description: Value of a property to set\n                          type: string\n                      required:\n                      - name\n                      - value\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  windowsOptions:\n                    description: |-\n                      The Windows specific settings applied to all containers.\n                      If unspecified, the options within a container's SecurityContext will be used.\n                      If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.\n                      Note that this field cannot be set when spec.os.name is linux.\n                    properties:\n                      gmsaCredentialSpec:\n                        description: |-\n                          GMSACredentialSpec is where the GMSA admission webhook\n                          (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the\n                          GMSA credential spec named by the GMSACredentialSpecName field.\n                        type: string\n                      gmsaCredentialSpecName:\n                        description: GMSACredentialSpecName is the name of the GMSA credential spec to use.\n                        type: string\n                      hostProcess:\n                        description: |-\n                          HostProcess determines if a container should be run as a 'Host Process' container.\n                          All of a Pod's containers must have the same effective HostProcess value\n                          (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).\n                          In addition, if HostProcess is true then HostNetwork must also be set to true.\n                        type: boolean\n                      runAsUserName:\n                        description: |-\n                          The UserName in Windows to run the entrypoint of the container process.\n                          Defaults to the user specified in image metadata if unspecified.\n                          May also be set in PodSecurityContext. If set in both SecurityContext and\n                          PodSecurityContext, the value specified in SecurityContext takes precedence.\n                        type: string\n                    type: object\n                type: object\n              serviceAccountName:\n                description: |-\n                  ServiceAccountName is the name of the ServiceAccount to use to run the\n                  Prometheus Pods.\n                type: string\n              serviceDiscoveryRole:\n                description: |-\n                  Defines the service discovery role used to discover targets from\n                  `ServiceMonitor` objects and Alertmanager endpoints.\n\n                  If set, the value should be either \"Endpoints\" or \"EndpointSlice\".\n                  If unset, the operator assumes the \"Endpoints\" role.\n                enum:\n                - Endpoints\n                - EndpointSlice\n                type: string\n              serviceMonitorNamespaceSelector:\n                description: |-\n                  Namespaces to match for ServicedMonitors discovery. An empty label selector\n                  matches all namespaces. A null label selector (default value) matches the current\n                  namespace only.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              serviceMonitorSelector:\n                description: |-\n                  ServiceMonitors to be selected for target discovery. An empty label\n                  selector matches all objects. A null label selector matches no objects.\n\n                  If `spec.serviceMonitorSelector`, `spec.podMonitorSelector`, `spec.probeSelector`\n                  and `spec.scrapeConfigSelector` are null, the Prometheus configuration is unmanaged.\n                  The Prometheus operator will ensure that the Prometheus configuration's\n                  Secret exists, but it is the responsibility of the user to provide the raw\n                  gzipped Prometheus configuration under the `prometheus.yaml.gz` key.\n                  This behavior is *deprecated* and will be removed in the next major version\n                  of the custom resource definition. It is recommended to use\n                  `spec.additionalScrapeConfigs` instead.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              serviceName:\n                description: |-\n                  The name of the service name used by the underlying StatefulSet(s) as the governing service.\n                  If defined, the Service  must be created before the Prometheus/PrometheusAgent resource in the same namespace and it must define a selector that matches the pod labels.\n                  If empty, the operator will create and manage a headless service named `prometheus-operated` for Prometheus resources,\n                  or `prometheus-agent-operated` for PrometheusAgent resources.\n                  When deploying multiple Prometheus/PrometheusAgent resources in the same namespace, it is recommended to specify a different value for each.\n                  See https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id for more details.\n                minLength: 1\n                type: string\n              shards:\n                description: |-\n                  Number of shards to distribute the scraped targets onto.\n\n                  `spec.replicas` multiplied by `spec.shards` is the total number of Pods\n                  being created.\n\n                  When not defined, the operator assumes only one shard.\n\n                  Note that scaling down shards will not reshard data onto the remaining\n                  instances, it must be manually moved. Increasing shards will not reshard\n                  data either but it will continue to be available from the same\n                  instances. To query globally, use either\n                  * Thanos sidecar + querier for query federation and Thanos Ruler for rules.\n                  * Remote-write to send metrics to a central location.\n\n                  By default, the sharding of targets is performed on:\n                  * The `__address__` target's metadata label for PodMonitor,\n                  ServiceMonitor and ScrapeConfig resources.\n                  * The `__param_target__` label for Probe resources.\n\n                  Users can define their own sharding implementation by setting the\n                  `__tmp_hash` label during the target discovery with relabeling\n                  configuration (either in the monitoring resources or via scrape class).\n\n                  You can also disable sharding on a specific target by setting the\n                  `__tmp_disable_sharding` label with relabeling configuration. When\n                  the label value isn't empty, all Prometheus shards will scrape the target.\n                format: int32\n                type: integer\n              storage:\n                description: Storage defines the storage used by Prometheus.\n                properties:\n                  disableMountSubPath:\n                    description: 'Deprecated: subPath usage will be removed in a future release.'\n                    type: boolean\n                  emptyDir:\n                    description: |-\n                      EmptyDirVolumeSource to be used by the StatefulSet.\n                      If specified, it takes precedence over `ephemeral` and `volumeClaimTemplate`.\n                      More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir\n                    properties:\n                      medium:\n                        description: |-\n                          medium represents what type of storage medium should back this directory.\n                          The default is \"\" which means to use the node's default medium.\n                          Must be an empty string (default) or Memory.\n                          More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                        type: string\n                      sizeLimit:\n                        anyOf:\n                        - type: integer\n                        - type: string\n                        description: |-\n                          sizeLimit is the total amount of local storage required for this EmptyDir volume.\n                          The size limit is also applicable for memory medium.\n                          The maximum usage on memory medium EmptyDir would be the minimum value between\n                          the SizeLimit specified here and the sum of memory limits of all containers in a pod.\n                          The default is nil which means that the limit is undefined.\n                          More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                        pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                        x-kubernetes-int-or-string: true\n                    type: object\n                  ephemeral:\n                    description: |-\n                      EphemeralVolumeSource to be used by the StatefulSet.\n                      This is a beta field in k8s 1.21 and GA in 1.15.\n                      For lower versions, starting with k8s 1.19, it requires enabling the GenericEphemeralVolume feature gate.\n                      More info: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes\n                    properties:\n                      volumeClaimTemplate:\n                        description: |-\n                          Will be used to create a stand-alone PVC to provision the volume.\n                          The pod in which this EphemeralVolumeSource is embedded will be the\n                          owner of the PVC, i.e. the PVC will be deleted together with the\n                          pod.  The name of the PVC will be `<pod name>-<volume name>` where\n                          `<volume name>` is the name from the `PodSpec.Volumes` array\n                          entry. Pod validation will reject the pod if the concatenated name\n                          is not valid for a PVC (for example, too long).\n\n                          An existing PVC with that name that is not owned by the pod\n                          will *not* be used for the pod to avoid using an unrelated\n                          volume by mistake. Starting the pod is then blocked until\n                          the unrelated PVC is removed. If such a pre-created PVC is\n                          meant to be used by the pod, the PVC has to updated with an\n                          owner reference to the pod once the pod exists. Normally\n                          this should not be necessary, but it may be useful when\n                          manually reconstructing a broken cluster.\n\n                          This field is read-only and no changes will be made by Kubernetes\n                          to the PVC after it has been created.\n\n                          Required, must not be nil.\n                        properties:\n                          metadata:\n                            description: |-\n                              May contain labels and annotations that will be copied into the PVC\n                              when creating it. No other fields are allowed and will be rejected during\n                              validation.\n                            type: object\n                          spec:\n                            description: |-\n                              The specification for the PersistentVolumeClaim. The entire content is\n                              copied unchanged into the PVC that gets created from this\n                              template. The same fields as in a PersistentVolumeClaim\n                              are also valid here.\n                            properties:\n                              accessModes:\n                                description: |-\n                                  accessModes contains the desired access modes the volume should have.\n                                  More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                                items:\n                                  type: string\n                                type: array\n                                x-kubernetes-list-type: atomic\n                              dataSource:\n                                description: |-\n                                  dataSource field can be used to specify either:\n                                  * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n                                  * An existing PVC (PersistentVolumeClaim)\n                                  If the provisioner or an external controller can support the specified data source,\n                                  it will create a new volume based on the contents of the specified data source.\n                                  When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\n                                  and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\n                                  If the namespace is specified, then dataSourceRef will not be copied to dataSource.\n                                properties:\n                                  apiGroup:\n                                    description: |-\n                                      APIGroup is the group for the resource being referenced.\n                                      If APIGroup is not specified, the specified Kind must be in the core API group.\n                                      For any other third-party types, APIGroup is required.\n                                    type: string\n                                  kind:\n                                    description: Kind is the type of resource being referenced\n                                    type: string\n                                  name:\n                                    description: Name is the name of resource being referenced\n                                    type: string\n                                required:\n                                - kind\n                                - name\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              dataSourceRef:\n                                description: |-\n                                  dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\n                                  volume is desired. This may be any object from a non-empty API group (non\n                                  core object) or a PersistentVolumeClaim object.\n                                  When this field is specified, volume binding will only succeed if the type of\n                                  the specified object matches some installed volume populator or dynamic\n                                  provisioner.\n                                  This field will replace the functionality of the dataSource field and as such\n                                  if both fields are non-empty, they must have the same value. For backwards\n                                  compatibility, when namespace isn't specified in dataSourceRef,\n                                  both fields (dataSource and dataSourceRef) will be set to the same\n                                  value automatically if one of them is empty and the other is non-empty.\n                                  When namespace is specified in dataSourceRef,\n                                  dataSource isn't set to the same value and must be empty.\n                                  There are three important differences between dataSource and dataSourceRef:\n                                  * While dataSource only allows two specific types of objects, dataSourceRef\n                                    allows any non-core object, as well as PersistentVolumeClaim objects.\n                                  * While dataSource ignores disallowed values (dropping them), dataSourceRef\n                                    preserves all values, and generates an error if a disallowed value is\n                                    specified.\n                                  * While dataSource only allows local objects, dataSourceRef allows objects\n                                    in any namespaces.\n                                  (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n                                  (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                properties:\n                                  apiGroup:\n                                    description: |-\n                                      APIGroup is the group for the resource being referenced.\n                                      If APIGroup is not specified, the specified Kind must be in the core API group.\n                                      For any other third-party types, APIGroup is required.\n                                    type: string\n                                  kind:\n                                    description: Kind is the type of resource being referenced\n                                    type: string\n                                  name:\n                                    description: Name is the name of resource being referenced\n                                    type: string\n                                  namespace:\n                                    description: |-\n                                      Namespace is the namespace of resource being referenced\n                                      Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n                                      (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                    type: string\n                                required:\n                                - kind\n                                - name\n                                type: object\n                              resources:\n                                description: |-\n                                  resources represents the minimum resources the volume should have.\n                                  If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\n                                  that are lower than previous value but must still be higher than capacity recorded in the\n                                  status field of the claim.\n                                  More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources\n                                properties:\n                                  limits:\n                                    additionalProperties:\n                                      anyOf:\n                                      - type: integer\n                                      - type: string\n                                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                      x-kubernetes-int-or-string: true\n                                    description: |-\n                                      Limits describes the maximum amount of compute resources allowed.\n                                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                    type: object\n                                  requests:\n                                    additionalProperties:\n                                      anyOf:\n                                      - type: integer\n                                      - type: string\n                                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                      x-kubernetes-int-or-string: true\n                                    description: |-\n                                      Requests describes the minimum amount of compute resources required.\n                                      If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                                      otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                    type: object\n                                type: object\n                              selector:\n                                description: selector is a label query over volumes to consider for binding.\n                                properties:\n                                  matchExpressions:\n                                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                    items:\n                                      description: |-\n                                        A label selector requirement is a selector that contains values, a key, and an operator that\n                                        relates the key and values.\n                                      properties:\n                                        key:\n                                          description: key is the label key that the selector applies to.\n                                          type: string\n                                        operator:\n                                          description: |-\n                                            operator represents a key's relationship to a set of values.\n                                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                                          type: string\n                                        values:\n                                          description: |-\n                                            values is an array of string values. If the operator is In or NotIn,\n                                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                            the values array must be empty. This array is replaced during a strategic\n                                            merge patch.\n                                          items:\n                                            type: string\n                                          type: array\n                                          x-kubernetes-list-type: atomic\n                                      required:\n                                      - key\n                                      - operator\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                  matchLabels:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                    type: object\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              storageClassName:\n                                description: |-\n                                  storageClassName is the name of the StorageClass required by the claim.\n                                  More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1\n                                type: string\n                              volumeAttributesClassName:\n                                description: |-\n                                  volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\n                                  If specified, the CSI driver will create or update the volume with the attributes defined\n                                  in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\n                                  it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\n                                  will be applied to the claim but it's not allowed to reset this field to empty string once it is set.\n                                  If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\n                                  will be set by the persistentvolume controller if it exists.\n                                  If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\n                                  set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\n                                  exists.\n                                  More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n                                  (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).\n                                type: string\n                              volumeMode:\n                                description: |-\n                                  volumeMode defines what type of volume is required by the claim.\n                                  Value of Filesystem is implied when not included in claim spec.\n                                type: string\n                              volumeName:\n                                description: volumeName is the binding reference to the PersistentVolume backing this claim.\n                                type: string\n                            type: object\n                        required:\n                        - spec\n                        type: object\n                    type: object\n                  volumeClaimTemplate:\n                    description: |-\n                      Defines the PVC spec to be used by the Prometheus StatefulSets.\n                      The easiest way to use a volume that cannot be automatically provisioned\n                      is to use a label selector alongside manually created PersistentVolumes.\n                    properties:\n                      apiVersion:\n                        description: |-\n                          APIVersion defines the versioned schema of this representation of an object.\n                          Servers should convert recognized schemas to the latest internal value, and\n                          may reject unrecognized values.\n                          More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n                        type: string\n                      kind:\n                        description: |-\n                          Kind is a string value representing the REST resource this object represents.\n                          Servers may infer this from the endpoint the client submits requests to.\n                          Cannot be updated.\n                          In CamelCase.\n                          More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n                        type: string\n                      metadata:\n                        description: EmbeddedMetadata contains metadata relevant to an EmbeddedResource.\n                        properties:\n                          annotations:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              Annotations is an unstructured key value map stored with a resource that may be\n                              set by external tools to store and retrieve arbitrary metadata. They are not\n                              queryable and should be preserved when modifying objects.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/\n                            type: object\n                          labels:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              Map of string keys and values that can be used to organize and categorize\n                              (scope and select) objects. May match selectors of replication controllers\n                              and services.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/\n                            type: object\n                          name:\n                            description: |-\n                              Name must be unique within a namespace. Is required when creating resources, although\n                              some resources may allow a client to request the generation of an appropriate name\n                              automatically. Name is primarily intended for creation idempotence and configuration\n                              definition.\n                              Cannot be updated.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\n                            type: string\n                        type: object\n                      spec:\n                        description: |-\n                          Defines the desired characteristics of a volume requested by a pod author.\n                          More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims\n                        properties:\n                          accessModes:\n                            description: |-\n                              accessModes contains the desired access modes the volume should have.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                            items:\n                              type: string\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          dataSource:\n                            description: |-\n                              dataSource field can be used to specify either:\n                              * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n                              * An existing PVC (PersistentVolumeClaim)\n                              If the provisioner or an external controller can support the specified data source,\n                              it will create a new volume based on the contents of the specified data source.\n                              When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\n                              and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\n                              If the namespace is specified, then dataSourceRef will not be copied to dataSource.\n                            properties:\n                              apiGroup:\n                                description: |-\n                                  APIGroup is the group for the resource being referenced.\n                                  If APIGroup is not specified, the specified Kind must be in the core API group.\n                                  For any other third-party types, APIGroup is required.\n                                type: string\n                              kind:\n                                description: Kind is the type of resource being referenced\n                                type: string\n                              name:\n                                description: Name is the name of resource being referenced\n                                type: string\n                            required:\n                            - kind\n                            - name\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          dataSourceRef:\n                            description: |-\n                              dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\n                              volume is desired. This may be any object from a non-empty API group (non\n                              core object) or a PersistentVolumeClaim object.\n                              When this field is specified, volume binding will only succeed if the type of\n                              the specified object matches some installed volume populator or dynamic\n                              provisioner.\n                              This field will replace the functionality of the dataSource field and as such\n                              if both fields are non-empty, they must have the same value. For backwards\n                              compatibility, when namespace isn't specified in dataSourceRef,\n                              both fields (dataSource and dataSourceRef) will be set to the same\n                              value automatically if one of them is empty and the other is non-empty.\n                              When namespace is specified in dataSourceRef,\n                              dataSource isn't set to the same value and must be empty.\n                              There are three important differences between dataSource and dataSourceRef:\n                              * While dataSource only allows two specific types of objects, dataSourceRef\n                                allows any non-core object, as well as PersistentVolumeClaim objects.\n                              * While dataSource ignores disallowed values (dropping them), dataSourceRef\n                                preserves all values, and generates an error if a disallowed value is\n                                specified.\n                              * While dataSource only allows local objects, dataSourceRef allows objects\n                                in any namespaces.\n                              (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n                              (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                            properties:\n                              apiGroup:\n                                description: |-\n                                  APIGroup is the group for the resource being referenced.\n                                  If APIGroup is not specified, the specified Kind must be in the core API group.\n                                  For any other third-party types, APIGroup is required.\n                                type: string\n                              kind:\n                                description: Kind is the type of resource being referenced\n                                type: string\n                              name:\n                                description: Name is the name of resource being referenced\n                                type: string\n                              namespace:\n                                description: |-\n                                  Namespace is the namespace of resource being referenced\n                                  Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n                                  (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                type: string\n                            required:\n                            - kind\n                            - name\n                            type: object\n                          resources:\n                            description: |-\n                              resources represents the minimum resources the volume should have.\n                              If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\n                              that are lower than previous value but must still be higher than capacity recorded in the\n                              status field of the claim.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources\n                            properties:\n                              limits:\n                                additionalProperties:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                  x-kubernetes-int-or-string: true\n                                description: |-\n                                  Limits describes the maximum amount of compute resources allowed.\n                                  More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                type: object\n                              requests:\n                                additionalProperties:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                  x-kubernetes-int-or-string: true\n                                description: |-\n                                  Requests describes the minimum amount of compute resources required.\n                                  If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                                  otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                                  More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                type: object\n                            type: object\n                          selector:\n                            description: selector is a label query over volumes to consider for binding.\n                            properties:\n                              matchExpressions:\n                                description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                items:\n                                  description: |-\n                                    A label selector requirement is a selector that contains values, a key, and an operator that\n                                    relates the key and values.\n                                  properties:\n                                    key:\n                                      description: key is the label key that the selector applies to.\n                                      type: string\n                                    operator:\n                                      description: |-\n                                        operator represents a key's relationship to a set of values.\n                                        Valid operators are In, NotIn, Exists and DoesNotExist.\n                                      type: string\n                                    values:\n                                      description: |-\n                                        values is an array of string values. If the operator is In or NotIn,\n                                        the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                        the values array must be empty. This array is replaced during a strategic\n                                        merge patch.\n                                      items:\n                                        type: string\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                  required:\n                                  - key\n                                  - operator\n                                  type: object\n                                type: array\n                                x-kubernetes-list-type: atomic\n                              matchLabels:\n                                additionalProperties:\n                                  type: string\n                                description: |-\n                                  matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                  map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                  operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                type: object\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          storageClassName:\n                            description: |-\n                              storageClassName is the name of the StorageClass required by the claim.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1\n                            type: string\n                          volumeAttributesClassName:\n                            description: |-\n                              volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\n                              If specified, the CSI driver will create or update the volume with the attributes defined\n                              in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\n                              it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\n                              will be applied to the claim but it's not allowed to reset this field to empty string once it is set.\n                              If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\n                              will be set by the persistentvolume controller if it exists.\n                              If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\n                              set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\n                              exists.\n                              More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n                              (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).\n                            type: string\n                          volumeMode:\n                            description: |-\n                              volumeMode defines what type of volume is required by the claim.\n                              Value of Filesystem is implied when not included in claim spec.\n                            type: string\n                          volumeName:\n                            description: volumeName is the binding reference to the PersistentVolume backing this claim.\n                            type: string\n                        type: object\n                      status:\n                        description: 'Deprecated: this field is never set.'\n                        properties:\n                          accessModes:\n                            description: |-\n                              accessModes contains the actual access modes the volume backing the PVC has.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                            items:\n                              type: string\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          allocatedResourceStatuses:\n                            additionalProperties:\n                              description: |-\n                                When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource\n                                that it does not recognizes, then it should ignore that update and let other controllers\n                                handle it.\n                              type: string\n                            description: \"allocatedResourceStatuses stores status of resource being resized for the given PVC.\\nKey names follow standard Kubernetes label syntax. Valid values are either:\\n\\t* Un-prefixed keys:\\n\\t\\t- storage - the capacity of the volume.\\n\\t* Custom resources must use implementation-defined prefixed names such as \\\"example.com/my-custom-resource\\\"\\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\\nreserved and hence may not be used.\\n\\nClaimResourceStatus can be in any of following states:\\n\\t- ControllerResizeInProgress:\\n\\t\\tState set when resize controller starts resizing the volume in control-plane.\\n\\t- ControllerResizeFailed:\\n\\t\\tState set when resize has failed in resize controller with a terminal error.\\n\\t- NodeResizePending:\\n\\t\\tState set when resize controller has finished resizing the volume but further resizing of\\n\\t\\tvolume is needed on the node.\\n\\t- NodeResizeInProgress:\\n\\t\\tState set when kubelet starts resizing the volume.\\n\\t- NodeResizeFailed:\\n\\t\\tState set when resizing has failed in kubelet with a terminal error. Transient errors don't set\\n\\t\\tNodeResizeFailed.\\nFor example: if expanding a PVC for more capacity - this field can be one of the following states:\\n\\t- pvc.status.allocatedResourceStatus['storage'] = \\\"ControllerResizeInProgress\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"ControllerResizeFailed\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"NodeResizePending\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"NodeResizeInProgress\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"NodeResizeFailed\\\"\\nWhen this field is not set, it means that no resize operation is in progress for the given PVC.\\n\\nA controller that receives PVC update with previously unknown resourceName or ClaimResourceStatus\\nshould ignore the update for the purpose it was designed. For example - a controller that\\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\\nresources associated with PVC.\\n\\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.\"\n                            type: object\n                            x-kubernetes-map-type: granular\n                          allocatedResources:\n                            additionalProperties:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                              x-kubernetes-int-or-string: true\n                            description: \"allocatedResources tracks the resources allocated to a PVC including its capacity.\\nKey names follow standard Kubernetes label syntax. Valid values are either:\\n\\t* Un-prefixed keys:\\n\\t\\t- storage - the capacity of the volume.\\n\\t* Custom resources must use implementation-defined prefixed names such as \\\"example.com/my-custom-resource\\\"\\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\\nreserved and hence may not be used.\\n\\nCapacity reported here may be larger than the actual capacity when a volume expansion operation\\nis requested.\\nFor storage quota, the larger value from allocatedResources and PVC.spec.resources is used.\\nIf allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.\\nIf a volume expansion capacity request is lowered, allocatedResources is only\\nlowered if there are no expansion operations in progress and if the actual volume capacity\\nis equal or lower than the requested capacity.\\n\\nA controller that receives PVC update with previously unknown resourceName\\nshould ignore the update for the purpose it was designed. For example - a controller that\\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\\nresources associated with PVC.\\n\\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.\"\n                            type: object\n                          capacity:\n                            additionalProperties:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                              x-kubernetes-int-or-string: true\n                            description: capacity represents the actual resources of the underlying volume.\n                            type: object\n                          conditions:\n                            description: |-\n                              conditions is the current Condition of persistent volume claim. If underlying persistent volume is being\n                              resized then the Condition will be set to 'Resizing'.\n                            items:\n                              description: PersistentVolumeClaimCondition contains details about state of pvc\n                              properties:\n                                lastProbeTime:\n                                  description: lastProbeTime is the time we probed the condition.\n                                  format: date-time\n                                  type: string\n                                lastTransitionTime:\n                                  description: lastTransitionTime is the time the condition transitioned from one status to another.\n                                  format: date-time\n                                  type: string\n                                message:\n                                  description: message is the human-readable message indicating details about last transition.\n                                  type: string\n                                reason:\n                                  description: |-\n                                    reason is a unique, this should be a short, machine understandable string that gives the reason\n                                    for condition's last transition. If it reports \"Resizing\" that means the underlying\n                                    persistent volume is being resized.\n                                  type: string\n                                status:\n                                  description: |-\n                                    Status is the status of the condition.\n                                    Can be True, False, Unknown.\n                                    More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=state%20of%20pvc-,conditions.status,-(string)%2C%20required\n                                  type: string\n                                type:\n                                  description: |-\n                                    Type is the type of the condition.\n                                    More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=set%20to%20%27ResizeStarted%27.-,PersistentVolumeClaimCondition,-contains%20details%20about\n                                  type: string\n                              required:\n                              - status\n                              - type\n                              type: object\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - type\n                            x-kubernetes-list-type: map\n                          currentVolumeAttributesClassName:\n                            description: |-\n                              currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using.\n                              When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim\n                              This is a beta field and requires enabling VolumeAttributesClass feature (off by default).\n                            type: string\n                          modifyVolumeStatus:\n                            description: |-\n                              ModifyVolumeStatus represents the status object of ControllerModifyVolume operation.\n                              When this is unset, there is no ModifyVolume operation being attempted.\n                              This is a beta field and requires enabling VolumeAttributesClass feature (off by default).\n                            properties:\n                              status:\n                                description: \"status is the status of the ControllerModifyVolume operation. It can be in any of following states:\\n - Pending\\n   Pending indicates that the PersistentVolumeClaim cannot be modified due to unmet requirements, such as\\n   the specified VolumeAttributesClass not existing.\\n - InProgress\\n   InProgress indicates that the volume is being modified.\\n - Infeasible\\n  Infeasible indicates that the request has been rejected as invalid by the CSI driver. To\\n\\t  resolve the error, a valid VolumeAttributesClass needs to be specified.\\nNote: New statuses can be added in the future. Consumers should check for unknown statuses and fail appropriately.\"\n                                type: string\n                              targetVolumeAttributesClassName:\n                                description: targetVolumeAttributesClassName is the name of the VolumeAttributesClass the PVC currently being reconciled\n                                type: string\n                            required:\n                            - status\n                            type: object\n                          phase:\n                            description: phase represents the current phase of PersistentVolumeClaim.\n                            type: string\n                        type: object\n                    type: object\n                type: object\n              targetLimit:\n                description: |-\n                  TargetLimit defines a limit on the number of scraped targets that will be accepted.\n                  Only valid in Prometheus versions 2.45.0 and newer.\n\n                  Note that the global limit only applies to scrape objects that don't specify an explicit limit value.\n                  If you want to enforce a maximum limit for all scrape objects, refer to enforcedTargetLimit.\n                format: int64\n                type: integer\n              terminationGracePeriodSeconds:\n                description: |-\n                  Optional duration in seconds the pod needs to terminate gracefully.\n                  Value must be non-negative integer. The value zero indicates stop immediately via\n                  the kill signal (no opportunity to shut down) which may lead to data corruption.\n\n                  Defaults to 600 seconds.\n                format: int64\n                minimum: 0\n                type: integer\n              tolerations:\n                description: Defines the Pods' tolerations if specified.\n                items:\n                  description: |-\n                    The pod this Toleration is attached to tolerates any taint that matches\n                    the triple <key,value,effect> using the matching operator <operator>.\n                  properties:\n                    effect:\n                      description: |-\n                        Effect indicates the taint effect to match. Empty means match all taint effects.\n                        When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.\n                      type: string\n                    key:\n                      description: |-\n                        Key is the taint key that the toleration applies to. Empty means match all taint keys.\n                        If the key is empty, operator must be Exists; this combination means to match all values and all keys.\n                      type: string\n                    operator:\n                      description: |-\n                        Operator represents a key's relationship to the value.\n                        Valid operators are Exists and Equal. Defaults to Equal.\n                        Exists is equivalent to wildcard for value, so that a pod can\n                        tolerate all taints of a particular category.\n                      type: string\n                    tolerationSeconds:\n                      description: |-\n                        TolerationSeconds represents the period of time the toleration (which must be\n                        of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,\n                        it is not set, which means tolerate the taint forever (do not evict). Zero and\n                        negative values will be treated as 0 (evict immediately) by the system.\n                      format: int64\n                      type: integer\n                    value:\n                      description: |-\n                        Value is the taint value the toleration matches to.\n                        If the operator is Exists, the value should be empty, otherwise just a regular string.\n                      type: string\n                  type: object\n                type: array\n              topologySpreadConstraints:\n                description: Defines the pod's topology spread constraints if specified.\n                items:\n                  properties:\n                    additionalLabelSelectors:\n                      description: Defines what Prometheus Operator managed labels should be added to labelSelector on the topologySpreadConstraint.\n                      enum:\n                      - OnResource\n                      - OnShard\n                      type: string\n                    labelSelector:\n                      description: |-\n                        LabelSelector is used to find matching pods.\n                        Pods that match this label selector are counted to determine the number of pods\n                        in their corresponding topology domain.\n                      properties:\n                        matchExpressions:\n                          description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                          items:\n                            description: |-\n                              A label selector requirement is a selector that contains values, a key, and an operator that\n                              relates the key and values.\n                            properties:\n                              key:\n                                description: key is the label key that the selector applies to.\n                                type: string\n                              operator:\n                                description: |-\n                                  operator represents a key's relationship to a set of values.\n                                  Valid operators are In, NotIn, Exists and DoesNotExist.\n                                type: string\n                              values:\n                                description: |-\n                                  values is an array of string values. If the operator is In or NotIn,\n                                  the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                  the values array must be empty. This array is replaced during a strategic\n                                  merge patch.\n                                items:\n                                  type: string\n                                type: array\n                                x-kubernetes-list-type: atomic\n                            required:\n                            - key\n                            - operator\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        matchLabels:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                            map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                            operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                          type: object\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    matchLabelKeys:\n                      description: |-\n                        MatchLabelKeys is a set of pod label keys to select the pods over which\n                        spreading will be calculated. The keys are used to lookup values from the\n                        incoming pod labels, those key-value labels are ANDed with labelSelector\n                        to select the group of existing pods over which spreading will be calculated\n                        for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.\n                        MatchLabelKeys cannot be set when LabelSelector isn't set.\n                        Keys that don't exist in the incoming pod labels will\n                        be ignored. A null or empty list means only match against labelSelector.\n\n                        This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default).\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    maxSkew:\n                      description: |-\n                        MaxSkew describes the degree to which pods may be unevenly distributed.\n                        When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference\n                        between the number of matching pods in the target topology and the global minimum.\n                        The global minimum is the minimum number of matching pods in an eligible domain\n                        or zero if the number of eligible domains is less than MinDomains.\n                        For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same\n                        labelSelector spread as 2/2/1:\n                        In this case, the global minimum is 1.\n                        | zone1 | zone2 | zone3 |\n                        |  P P  |  P P  |   P   |\n                        - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2;\n                        scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2)\n                        violate MaxSkew(1).\n                        - if MaxSkew is 2, incoming pod can be scheduled onto any zone.\n                        When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence\n                        to topologies that satisfy it.\n                        It's a required field. Default value is 1 and 0 is not allowed.\n                      format: int32\n                      type: integer\n                    minDomains:\n                      description: |-\n                        MinDomains indicates a minimum number of eligible domains.\n                        When the number of eligible domains with matching topology keys is less than minDomains,\n                        Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed.\n                        And when the number of eligible domains with matching topology keys equals or greater than minDomains,\n                        this value has no effect on scheduling.\n                        As a result, when the number of eligible domains is less than minDomains,\n                        scheduler won't schedule more than maxSkew Pods to those domains.\n                        If value is nil, the constraint behaves as if MinDomains is equal to 1.\n                        Valid values are integers greater than 0.\n                        When value is not nil, WhenUnsatisfiable must be DoNotSchedule.\n\n                        For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same\n                        labelSelector spread as 2/2/2:\n                        | zone1 | zone2 | zone3 |\n                        |  P P  |  P P  |  P P  |\n                        The number of domains is less than 5(MinDomains), so \"global minimum\" is treated as 0.\n                        In this situation, new pod with the same labelSelector cannot be scheduled,\n                        because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones,\n                        it will violate MaxSkew.\n                      format: int32\n                      type: integer\n                    nodeAffinityPolicy:\n                      description: |-\n                        NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector\n                        when calculating pod topology spread skew. Options are:\n                        - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations.\n                        - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.\n\n                        If this value is nil, the behavior is equivalent to the Honor policy.\n                      type: string\n                    nodeTaintsPolicy:\n                      description: |-\n                        NodeTaintsPolicy indicates how we will treat node taints when calculating\n                        pod topology spread skew. Options are:\n                        - Honor: nodes without taints, along with tainted nodes for which the incoming pod\n                        has a toleration, are included.\n                        - Ignore: node taints are ignored. All nodes are included.\n\n                        If this value is nil, the behavior is equivalent to the Ignore policy.\n                      type: string\n                    topologyKey:\n                      description: |-\n                        TopologyKey is the key of node labels. Nodes that have a label with this key\n                        and identical values are considered to be in the same topology.\n                        We consider each <key, value> as a \"bucket\", and try to put balanced number\n                        of pods into each bucket.\n                        We define a domain as a particular instance of a topology.\n                        Also, we define an eligible domain as a domain whose nodes meet the requirements of\n                        nodeAffinityPolicy and nodeTaintsPolicy.\n                        e.g. If TopologyKey is \"kubernetes.io/hostname\", each Node is a domain of that topology.\n                        And, if TopologyKey is \"topology.kubernetes.io/zone\", each zone is a domain of that topology.\n                        It's a required field.\n                      type: string\n                    whenUnsatisfiable:\n                      description: |-\n                        WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy\n                        the spread constraint.\n                        - DoNotSchedule (default) tells the scheduler not to schedule it.\n                        - ScheduleAnyway tells the scheduler to schedule the pod in any location,\n                          but giving higher precedence to topologies that would help reduce the\n                          skew.\n                        A constraint is considered \"Unsatisfiable\" for an incoming pod\n                        if and only if every possible node assignment for that pod would violate\n                        \"MaxSkew\" on some topology.\n                        For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same\n                        labelSelector spread as 3/1/1:\n                        | zone1 | zone2 | zone3 |\n                        | P P P |   P   |   P   |\n                        If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled\n                        to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies\n                        MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler\n                        won't make it *more* imbalanced.\n                        It's a required field.\n                      type: string\n                  required:\n                  - maxSkew\n                  - topologyKey\n                  - whenUnsatisfiable\n                  type: object\n                type: array\n              tracingConfig:\n                description: |-\n                  TracingConfig configures tracing in Prometheus.\n\n                  This is an *experimental feature*, it may change in any upcoming release\n                  in a breaking way.\n                properties:\n                  clientType:\n                    description: Client used to export the traces. Supported values are `http` or `grpc`.\n                    enum:\n                    - http\n                    - grpc\n                    type: string\n                  compression:\n                    description: Compression key for supported compression types. The only supported value is `gzip`.\n                    enum:\n                    - gzip\n                    type: string\n                  endpoint:\n                    description: Endpoint to send the traces to. Should be provided in format <host>:<port>.\n                    minLength: 1\n                    type: string\n                  headers:\n                    additionalProperties:\n                      type: string\n                    description: Key-value pairs to be used as headers associated with gRPC or HTTP requests.\n                    type: object\n                  insecure:\n                    description: If disabled, the client will use a secure connection.\n                    type: boolean\n                  samplingFraction:\n                    anyOf:\n                    - type: integer\n                    - type: string\n                    description: Sets the probability a given trace will be sampled. Must be a float from 0 through 1.\n                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                    x-kubernetes-int-or-string: true\n                  timeout:\n                    description: Maximum time the exporter will wait for each batch export.\n                    pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                    type: string\n                  tlsConfig:\n                    description: TLS Config to use when sending traces.\n                    properties:\n                      ca:\n                        description: Certificate authority used when verifying server certificates.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      caFile:\n                        description: Path to the CA cert in the Prometheus container to use for the targets.\n                        type: string\n                      cert:\n                        description: Client certificate to present when doing client-authentication.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      certFile:\n                        description: Path to the client cert file in the Prometheus container for the targets.\n                        type: string\n                      insecureSkipVerify:\n                        description: Disable target certificate validation.\n                        type: boolean\n                      keyFile:\n                        description: Path to the client key file in the Prometheus container for the targets.\n                        type: string\n                      keySecret:\n                        description: Secret containing the client key file for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: |-\n                          Maximum acceptable TLS version.\n\n                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      minVersion:\n                        description: |-\n                          Minimum acceptable TLS version.\n\n                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      serverName:\n                        description: Used to verify the hostname for the targets.\n                        type: string\n                    type: object\n                required:\n                - endpoint\n                type: object\n              tsdb:\n                description: |-\n                  Defines the runtime reloadable configuration of the timeseries database(TSDB).\n                  It requires Prometheus >= v2.39.0 or PrometheusAgent >= v2.54.0.\n                properties:\n                  outOfOrderTimeWindow:\n                    description: |-\n                      Configures how old an out-of-order/out-of-bounds sample can be with\n                      respect to the TSDB max time.\n\n                      An out-of-order/out-of-bounds sample is ingested into the TSDB as long as\n                      the timestamp of the sample is >= (TSDB.MaxTime - outOfOrderTimeWindow).\n\n                      This is an *experimental feature*, it may change in any upcoming release\n                      in a breaking way.\n\n                      It requires Prometheus >= v2.39.0 or PrometheusAgent >= v2.54.0.\n                    pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                    type: string\n                type: object\n              version:\n                description: |-\n                  Version of Prometheus being deployed. The operator uses this information\n                  to generate the Prometheus StatefulSet + configuration files.\n\n                  If not specified, the operator assumes the latest upstream version of\n                  Prometheus available at the time when the version of the operator was\n                  released.\n                type: string\n              volumeMounts:\n                description: |-\n                  VolumeMounts allows the configuration of additional VolumeMounts.\n\n                  VolumeMounts will be appended to other VolumeMounts in the 'prometheus'\n                  container, that are generated as a result of StorageSpec objects.\n                items:\n                  description: VolumeMount describes a mounting of a Volume within a container.\n                  properties:\n                    mountPath:\n                      description: |-\n                        Path within the container at which the volume should be mounted.  Must\n                        not contain ':'.\n                      type: string\n                    mountPropagation:\n                      description: |-\n                        mountPropagation determines how mounts are propagated from the host\n                        to container and the other way around.\n                        When not set, MountPropagationNone is used.\n                        This field is beta in 1.10.\n                        When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                        (which defaults to None).\n                      type: string\n                    name:\n                      description: This must match the Name of a Volume.\n                      type: string\n                    readOnly:\n                      description: |-\n                        Mounted read-only if true, read-write otherwise (false or unspecified).\n                        Defaults to false.\n                      type: boolean\n                    recursiveReadOnly:\n                      description: |-\n                        RecursiveReadOnly specifies whether read-only mounts should be handled\n                        recursively.\n\n                        If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                        If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                        recursively read-only.  If this field is set to IfPossible, the mount is made\n                        recursively read-only, if it is supported by the container runtime.  If this\n                        field is set to Enabled, the mount is made recursively read-only if it is\n                        supported by the container runtime, otherwise the pod will not be started and\n                        an error will be generated to indicate the reason.\n\n                        If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                        None (or be unspecified, which defaults to None).\n\n                        If this field is not specified, it is treated as an equivalent of Disabled.\n                      type: string\n                    subPath:\n                      description: |-\n                        Path within the volume from which the container's volume should be mounted.\n                        Defaults to \"\" (volume's root).\n                      type: string\n                    subPathExpr:\n                      description: |-\n                        Expanded path within the volume from which the container's volume should be mounted.\n                        Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                        Defaults to \"\" (volume's root).\n                        SubPathExpr and SubPath are mutually exclusive.\n                      type: string\n                  required:\n                  - mountPath\n                  - name\n                  type: object\n                type: array\n              volumes:\n                description: |-\n                  Volumes allows the configuration of additional volumes on the output\n                  StatefulSet definition. Volumes specified will be appended to other\n                  volumes that are generated as a result of StorageSpec objects.\n                items:\n                  description: Volume represents a named volume in a pod that may be accessed by any container in the pod.\n                  properties:\n                    awsElasticBlockStore:\n                      description: |-\n                        awsElasticBlockStore represents an AWS Disk resource that is attached to a\n                        kubelet's host machine and then exposed to the pod.\n                        Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree\n                        awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                          type: string\n                        partition:\n                          description: |-\n                            partition is the partition in the volume that you want to mount.\n                            If omitted, the default is to mount by volume name.\n                            Examples: For volume /dev/sda1, you specify the partition as \"1\".\n                            Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty).\n                          format: int32\n                          type: integer\n                        readOnly:\n                          description: |-\n                            readOnly value true will force the readOnly setting in VolumeMounts.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                          type: boolean\n                        volumeID:\n                          description: |-\n                            volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume).\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                          type: string\n                      required:\n                      - volumeID\n                      type: object\n                    azureDisk:\n                      description: |-\n                        azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.\n                        Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type\n                        are redirected to the disk.csi.azure.com CSI driver.\n                      properties:\n                        cachingMode:\n                          description: 'cachingMode is the Host Caching mode: None, Read Only, Read Write.'\n                          type: string\n                        diskName:\n                          description: diskName is the Name of the data disk in the blob storage\n                          type: string\n                        diskURI:\n                          description: diskURI is the URI of data disk in the blob storage\n                          type: string\n                        fsType:\n                          default: ext4\n                          description: |-\n                            fsType is Filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        kind:\n                          description: 'kind expected values are Shared: multiple blob disks per storage account  Dedicated: single blob disk per storage account  Managed: azure managed data disk (only in managed availability set). defaults to shared'\n                          type: string\n                        readOnly:\n                          default: false\n                          description: |-\n                            readOnly Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                      required:\n                      - diskName\n                      - diskURI\n                      type: object\n                    azureFile:\n                      description: |-\n                        azureFile represents an Azure File Service mount on the host and bind mount to the pod.\n                        Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type\n                        are redirected to the file.csi.azure.com CSI driver.\n                      properties:\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretName:\n                          description: secretName is the  name of secret that contains Azure Storage Account Name and Key\n                          type: string\n                        shareName:\n                          description: shareName is the azure share Name\n                          type: string\n                      required:\n                      - secretName\n                      - shareName\n                      type: object\n                    cephfs:\n                      description: |-\n                        cephFS represents a Ceph FS mount on the host that shares a pod's lifetime.\n                        Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported.\n                      properties:\n                        monitors:\n                          description: |-\n                            monitors is Required: Monitors is a collection of Ceph monitors\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        path:\n                          description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /'\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly is Optional: Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          type: boolean\n                        secretFile:\n                          description: |-\n                            secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          type: string\n                        secretRef:\n                          description: |-\n                            secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty.\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        user:\n                          description: |-\n                            user is optional: User is the rados user name, default is admin\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          type: string\n                      required:\n                      - monitors\n                      type: object\n                    cinder:\n                      description: |-\n                        cinder represents a cinder volume attached and mounted on kubelets host machine.\n                        Deprecated: Cinder is deprecated. All operations for the in-tree cinder type\n                        are redirected to the cinder.csi.openstack.org CSI driver.\n                        More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                            More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef is optional: points to a secret object containing parameters used to connect\n                            to OpenStack.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        volumeID:\n                          description: |-\n                            volumeID used to identify the volume in cinder.\n                            More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                          type: string\n                      required:\n                      - volumeID\n                      type: object\n                    configMap:\n                      description: configMap represents a configMap that should populate this volume\n                      properties:\n                        defaultMode:\n                          description: |-\n                            defaultMode is optional: mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                            Defaults to 0644.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        items:\n                          description: |-\n                            items if unspecified, each key-value pair in the Data field of the referenced\n                            ConfigMap will be projected into the volume as a file whose name is the\n                            key and content is the value. If specified, the listed keys will be\n                            projected into the specified paths, and unlisted keys will not be\n                            present. If a key is specified which is not present in the ConfigMap,\n                            the volume setup will error unless it is marked optional. Paths must be\n                            relative and may not contain the '..' path or start with '..'.\n                          items:\n                            description: Maps a string key to a path within a volume.\n                            properties:\n                              key:\n                                description: key is the key to project.\n                                type: string\n                              mode:\n                                description: |-\n                                  mode is Optional: mode bits used to set permissions on this file.\n                                  Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                  YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                  If not specified, the volume defaultMode will be used.\n                                  This might be in conflict with other options that affect the file\n                                  mode, like fsGroup, and the result can be other mode bits set.\n                                format: int32\n                                type: integer\n                              path:\n                                description: |-\n                                  path is the relative path of the file to map the key to.\n                                  May not be an absolute path.\n                                  May not contain the path element '..'.\n                                  May not start with the string '..'.\n                                type: string\n                            required:\n                            - key\n                            - path\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: optional specify whether the ConfigMap or its keys must be defined\n                          type: boolean\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    csi:\n                      description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers.\n                      properties:\n                        driver:\n                          description: |-\n                            driver is the name of the CSI driver that handles this volume.\n                            Consult with your admin for the correct name as registered in the cluster.\n                          type: string\n                        fsType:\n                          description: |-\n                            fsType to mount. Ex. \"ext4\", \"xfs\", \"ntfs\".\n                            If not provided, the empty value is passed to the associated CSI driver\n                            which will determine the default filesystem to apply.\n                          type: string\n                        nodePublishSecretRef:\n                          description: |-\n                            nodePublishSecretRef is a reference to the secret object containing\n                            sensitive information to pass to the CSI driver to complete the CSI\n                            NodePublishVolume and NodeUnpublishVolume calls.\n                            This field is optional, and  may be empty if no secret is required. If the\n                            secret object contains more than one secret, all secret references are passed.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        readOnly:\n                          description: |-\n                            readOnly specifies a read-only configuration for the volume.\n                            Defaults to false (read/write).\n                          type: boolean\n                        volumeAttributes:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            volumeAttributes stores driver-specific properties that are passed to the CSI\n                            driver. Consult your driver's documentation for supported values.\n                          type: object\n                      required:\n                      - driver\n                      type: object\n                    downwardAPI:\n                      description: downwardAPI represents downward API about the pod that should populate this volume\n                      properties:\n                        defaultMode:\n                          description: |-\n                            Optional: mode bits to use on created files by default. Must be a\n                            Optional: mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                            Defaults to 0644.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        items:\n                          description: Items is a list of downward API volume file\n                          items:\n                            description: DownwardAPIVolumeFile represents information to create the file containing the pod field\n                            properties:\n                              fieldRef:\n                                description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.'\n                                properties:\n                                  apiVersion:\n                                    description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                    type: string\n                                  fieldPath:\n                                    description: Path of the field to select in the specified API version.\n                                    type: string\n                                required:\n                                - fieldPath\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              mode:\n                                description: |-\n                                  Optional: mode bits used to set permissions on this file, must be an octal value\n                                  between 0000 and 0777 or a decimal value between 0 and 511.\n                                  YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                  If not specified, the volume defaultMode will be used.\n                                  This might be in conflict with other options that affect the file\n                                  mode, like fsGroup, and the result can be other mode bits set.\n                                format: int32\n                                type: integer\n                              path:\n                                description: 'Required: Path is  the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..'''\n                                type: string\n                              resourceFieldRef:\n                                description: |-\n                                  Selects a resource of the container: only resources limits and requests\n                                  (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.\n                                properties:\n                                  containerName:\n                                    description: 'Container name: required for volumes, optional for env vars'\n                                    type: string\n                                  divisor:\n                                    anyOf:\n                                    - type: integer\n                                    - type: string\n                                    description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                    x-kubernetes-int-or-string: true\n                                  resource:\n                                    description: 'Required: resource to select'\n                                    type: string\n                                required:\n                                - resource\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            required:\n                            - path\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    emptyDir:\n                      description: |-\n                        emptyDir represents a temporary directory that shares a pod's lifetime.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                      properties:\n                        medium:\n                          description: |-\n                            medium represents what type of storage medium should back this directory.\n                            The default is \"\" which means to use the node's default medium.\n                            Must be an empty string (default) or Memory.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                          type: string\n                        sizeLimit:\n                          anyOf:\n                          - type: integer\n                          - type: string\n                          description: |-\n                            sizeLimit is the total amount of local storage required for this EmptyDir volume.\n                            The size limit is also applicable for memory medium.\n                            The maximum usage on memory medium EmptyDir would be the minimum value between\n                            the SizeLimit specified here and the sum of memory limits of all containers in a pod.\n                            The default is nil which means that the limit is undefined.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                          pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                          x-kubernetes-int-or-string: true\n                      type: object\n                    ephemeral:\n                      description: |-\n                        ephemeral represents a volume that is handled by a cluster storage driver.\n                        The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts,\n                        and deleted when the pod is removed.\n\n                        Use this if:\n                        a) the volume is only needed while the pod runs,\n                        b) features of normal volumes like restoring from snapshot or capacity\n                           tracking are needed,\n                        c) the storage driver is specified through a storage class, and\n                        d) the storage driver supports dynamic volume provisioning through\n                           a PersistentVolumeClaim (see EphemeralVolumeSource for more\n                           information on the connection between this volume type\n                           and PersistentVolumeClaim).\n\n                        Use PersistentVolumeClaim or one of the vendor-specific\n                        APIs for volumes that persist for longer than the lifecycle\n                        of an individual pod.\n\n                        Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to\n                        be used that way - see the documentation of the driver for\n                        more information.\n\n                        A pod can use both types of ephemeral volumes and\n                        persistent volumes at the same time.\n                      properties:\n                        volumeClaimTemplate:\n                          description: |-\n                            Will be used to create a stand-alone PVC to provision the volume.\n                            The pod in which this EphemeralVolumeSource is embedded will be the\n                            owner of the PVC, i.e. the PVC will be deleted together with the\n                            pod.  The name of the PVC will be `<pod name>-<volume name>` where\n                            `<volume name>` is the name from the `PodSpec.Volumes` array\n                            entry. Pod validation will reject the pod if the concatenated name\n                            is not valid for a PVC (for example, too long).\n\n                            An existing PVC with that name that is not owned by the pod\n                            will *not* be used for the pod to avoid using an unrelated\n                            volume by mistake. Starting the pod is then blocked until\n                            the unrelated PVC is removed. If such a pre-created PVC is\n                            meant to be used by the pod, the PVC has to updated with an\n                            owner reference to the pod once the pod exists. Normally\n                            this should not be necessary, but it may be useful when\n                            manually reconstructing a broken cluster.\n\n                            This field is read-only and no changes will be made by Kubernetes\n                            to the PVC after it has been created.\n\n                            Required, must not be nil.\n                          properties:\n                            metadata:\n                              description: |-\n                                May contain labels and annotations that will be copied into the PVC\n                                when creating it. No other fields are allowed and will be rejected during\n                                validation.\n                              type: object\n                            spec:\n                              description: |-\n                                The specification for the PersistentVolumeClaim. The entire content is\n                                copied unchanged into the PVC that gets created from this\n                                template. The same fields as in a PersistentVolumeClaim\n                                are also valid here.\n                              properties:\n                                accessModes:\n                                  description: |-\n                                    accessModes contains the desired access modes the volume should have.\n                                    More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                dataSource:\n                                  description: |-\n                                    dataSource field can be used to specify either:\n                                    * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n                                    * An existing PVC (PersistentVolumeClaim)\n                                    If the provisioner or an external controller can support the specified data source,\n                                    it will create a new volume based on the contents of the specified data source.\n                                    When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\n                                    and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\n                                    If the namespace is specified, then dataSourceRef will not be copied to dataSource.\n                                  properties:\n                                    apiGroup:\n                                      description: |-\n                                        APIGroup is the group for the resource being referenced.\n                                        If APIGroup is not specified, the specified Kind must be in the core API group.\n                                        For any other third-party types, APIGroup is required.\n                                      type: string\n                                    kind:\n                                      description: Kind is the type of resource being referenced\n                                      type: string\n                                    name:\n                                      description: Name is the name of resource being referenced\n                                      type: string\n                                  required:\n                                  - kind\n                                  - name\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                dataSourceRef:\n                                  description: |-\n                                    dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\n                                    volume is desired. This may be any object from a non-empty API group (non\n                                    core object) or a PersistentVolumeClaim object.\n                                    When this field is specified, volume binding will only succeed if the type of\n                                    the specified object matches some installed volume populator or dynamic\n                                    provisioner.\n                                    This field will replace the functionality of the dataSource field and as such\n                                    if both fields are non-empty, they must have the same value. For backwards\n                                    compatibility, when namespace isn't specified in dataSourceRef,\n                                    both fields (dataSource and dataSourceRef) will be set to the same\n                                    value automatically if one of them is empty and the other is non-empty.\n                                    When namespace is specified in dataSourceRef,\n                                    dataSource isn't set to the same value and must be empty.\n                                    There are three important differences between dataSource and dataSourceRef:\n                                    * While dataSource only allows two specific types of objects, dataSourceRef\n                                      allows any non-core object, as well as PersistentVolumeClaim objects.\n                                    * While dataSource ignores disallowed values (dropping them), dataSourceRef\n                                      preserves all values, and generates an error if a disallowed value is\n                                      specified.\n                                    * While dataSource only allows local objects, dataSourceRef allows objects\n                                      in any namespaces.\n                                    (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n                                    (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                  properties:\n                                    apiGroup:\n                                      description: |-\n                                        APIGroup is the group for the resource being referenced.\n                                        If APIGroup is not specified, the specified Kind must be in the core API group.\n                                        For any other third-party types, APIGroup is required.\n                                      type: string\n                                    kind:\n                                      description: Kind is the type of resource being referenced\n                                      type: string\n                                    name:\n                                      description: Name is the name of resource being referenced\n                                      type: string\n                                    namespace:\n                                      description: |-\n                                        Namespace is the namespace of resource being referenced\n                                        Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n                                        (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                      type: string\n                                  required:\n                                  - kind\n                                  - name\n                                  type: object\n                                resources:\n                                  description: |-\n                                    resources represents the minimum resources the volume should have.\n                                    If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\n                                    that are lower than previous value but must still be higher than capacity recorded in the\n                                    status field of the claim.\n                                    More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources\n                                  properties:\n                                    limits:\n                                      additionalProperties:\n                                        anyOf:\n                                        - type: integer\n                                        - type: string\n                                        pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                        x-kubernetes-int-or-string: true\n                                      description: |-\n                                        Limits describes the maximum amount of compute resources allowed.\n                                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                      type: object\n                                    requests:\n                                      additionalProperties:\n                                        anyOf:\n                                        - type: integer\n                                        - type: string\n                                        pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                        x-kubernetes-int-or-string: true\n                                      description: |-\n                                        Requests describes the minimum amount of compute resources required.\n                                        If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                                        otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                      type: object\n                                  type: object\n                                selector:\n                                  description: selector is a label query over volumes to consider for binding.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                storageClassName:\n                                  description: |-\n                                    storageClassName is the name of the StorageClass required by the claim.\n                                    More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1\n                                  type: string\n                                volumeAttributesClassName:\n                                  description: |-\n                                    volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\n                                    If specified, the CSI driver will create or update the volume with the attributes defined\n                                    in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\n                                    it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\n                                    will be applied to the claim but it's not allowed to reset this field to empty string once it is set.\n                                    If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\n                                    will be set by the persistentvolume controller if it exists.\n                                    If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\n                                    set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\n                                    exists.\n                                    More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n                                    (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).\n                                  type: string\n                                volumeMode:\n                                  description: |-\n                                    volumeMode defines what type of volume is required by the claim.\n                                    Value of Filesystem is implied when not included in claim spec.\n                                  type: string\n                                volumeName:\n                                  description: volumeName is the binding reference to the PersistentVolume backing this claim.\n                                  type: string\n                              type: object\n                          required:\n                          - spec\n                          type: object\n                      type: object\n                    fc:\n                      description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        lun:\n                          description: 'lun is Optional: FC target lun number'\n                          format: int32\n                          type: integer\n                        readOnly:\n                          description: |-\n                            readOnly is Optional: Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        targetWWNs:\n                          description: 'targetWWNs is Optional: FC target worldwide names (WWNs)'\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        wwids:\n                          description: |-\n                            wwids Optional: FC volume world wide identifiers (wwids)\n                            Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    flexVolume:\n                      description: |-\n                        flexVolume represents a generic volume resource that is\n                        provisioned/attached using an exec based plugin.\n                        Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead.\n                      properties:\n                        driver:\n                          description: driver is the name of the driver to use for this volume.\n                          type: string\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". The default filesystem depends on FlexVolume script.\n                          type: string\n                        options:\n                          additionalProperties:\n                            type: string\n                          description: 'options is Optional: this field holds extra command options if any.'\n                          type: object\n                        readOnly:\n                          description: |-\n                            readOnly is Optional: defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef is Optional: secretRef is reference to the secret object containing\n                            sensitive information to pass to the plugin scripts. This may be\n                            empty if no secret object is specified. If the secret object\n                            contains more than one secret, all secrets are passed to the plugin\n                            scripts.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      required:\n                      - driver\n                      type: object\n                    flocker:\n                      description: |-\n                        flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running.\n                        Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported.\n                      properties:\n                        datasetName:\n                          description: |-\n                            datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker\n                            should be considered as deprecated\n                          type: string\n                        datasetUUID:\n                          description: datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset\n                          type: string\n                      type: object\n                    gcePersistentDisk:\n                      description: |-\n                        gcePersistentDisk represents a GCE Disk resource that is attached to a\n                        kubelet's host machine and then exposed to the pod.\n                        Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree\n                        gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          type: string\n                        partition:\n                          description: |-\n                            partition is the partition in the volume that you want to mount.\n                            If omitted, the default is to mount by volume name.\n                            Examples: For volume /dev/sda1, you specify the partition as \"1\".\n                            Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty).\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          format: int32\n                          type: integer\n                        pdName:\n                          description: |-\n                            pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the ReadOnly setting in VolumeMounts.\n                            Defaults to false.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          type: boolean\n                      required:\n                      - pdName\n                      type: object\n                    gitRepo:\n                      description: |-\n                        gitRepo represents a git repository at a particular revision.\n                        Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an\n                        EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir\n                        into the Pod's container.\n                      properties:\n                        directory:\n                          description: |-\n                            directory is the target directory name.\n                            Must not contain or start with '..'.  If '.' is supplied, the volume directory will be the\n                            git repository.  Otherwise, if specified, the volume will contain the git repository in\n                            the subdirectory with the given name.\n                          type: string\n                        repository:\n                          description: repository is the URL\n                          type: string\n                        revision:\n                          description: revision is the commit hash for the specified revision.\n                          type: string\n                      required:\n                      - repository\n                      type: object\n                    glusterfs:\n                      description: |-\n                        glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime.\n                        Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported.\n                        More info: https://examples.k8s.io/volumes/glusterfs/README.md\n                      properties:\n                        endpoints:\n                          description: |-\n                            endpoints is the endpoint name that details Glusterfs topology.\n                            More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod\n                          type: string\n                        path:\n                          description: |-\n                            path is the Glusterfs volume path.\n                            More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the Glusterfs volume to be mounted with read-only permissions.\n                            Defaults to false.\n                            More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod\n                          type: boolean\n                      required:\n                      - endpoints\n                      - path\n                      type: object\n                    hostPath:\n                      description: |-\n                        hostPath represents a pre-existing file or directory on the host\n                        machine that is directly exposed to the container. This is generally\n                        used for system agents or other privileged things that are allowed\n                        to see the host machine. Most containers will NOT need this.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath\n                      properties:\n                        path:\n                          description: |-\n                            path of the directory on the host.\n                            If the path is a symlink, it will follow the link to the real path.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath\n                          type: string\n                        type:\n                          description: |-\n                            type for HostPath Volume\n                            Defaults to \"\"\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath\n                          type: string\n                      required:\n                      - path\n                      type: object\n                    image:\n                      description: |-\n                        image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine.\n                        The volume is resolved at pod startup depending on which PullPolicy value is provided:\n\n                        - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails.\n                        - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.\n                        - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n\n                        The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation.\n                        A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message.\n                        The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field.\n                        The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images.\n                        The volume will be mounted read-only (ro) and non-executable files (noexec).\n                        Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33.\n                        The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.\n                      properties:\n                        pullPolicy:\n                          description: |-\n                            Policy for pulling OCI objects. Possible values are:\n                            Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails.\n                            Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.\n                            IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n                            Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.\n                          type: string\n                        reference:\n                          description: |-\n                            Required: Image or artifact reference to be used.\n                            Behaves in the same way as pod.spec.containers[*].image.\n                            Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets.\n                            More info: https://kubernetes.io/docs/concepts/containers/images\n                            This field is optional to allow higher level config management to default or override\n                            container images in workload controllers like Deployments and StatefulSets.\n                          type: string\n                      type: object\n                    iscsi:\n                      description: |-\n                        iscsi represents an ISCSI Disk resource that is attached to a\n                        kubelet's host machine and then exposed to the pod.\n                        More info: https://examples.k8s.io/volumes/iscsi/README.md\n                      properties:\n                        chapAuthDiscovery:\n                          description: chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication\n                          type: boolean\n                        chapAuthSession:\n                          description: chapAuthSession defines whether support iSCSI Session CHAP authentication\n                          type: boolean\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi\n                          type: string\n                        initiatorName:\n                          description: |-\n                            initiatorName is the custom iSCSI Initiator Name.\n                            If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface\n                            <target portal>:<volume name> will be created for the connection.\n                          type: string\n                        iqn:\n                          description: iqn is the target iSCSI Qualified Name.\n                          type: string\n                        iscsiInterface:\n                          default: default\n                          description: |-\n                            iscsiInterface is the interface Name that uses an iSCSI transport.\n                            Defaults to 'default' (tcp).\n                          type: string\n                        lun:\n                          description: lun represents iSCSI Target Lun number.\n                          format: int32\n                          type: integer\n                        portals:\n                          description: |-\n                            portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port\n                            is other than default (typically TCP ports 860 and 3260).\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        readOnly:\n                          description: |-\n                            readOnly here will force the ReadOnly setting in VolumeMounts.\n                            Defaults to false.\n                          type: boolean\n                        secretRef:\n                          description: secretRef is the CHAP Secret for iSCSI target and initiator authentication\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        targetPortal:\n                          description: |-\n                            targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port\n                            is other than default (typically TCP ports 860 and 3260).\n                          type: string\n                      required:\n                      - iqn\n                      - lun\n                      - targetPortal\n                      type: object\n                    name:\n                      description: |-\n                        name of the volume.\n                        Must be a DNS_LABEL and unique within the pod.\n                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                      type: string\n                    nfs:\n                      description: |-\n                        nfs represents an NFS mount on the host that shares a pod's lifetime\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                      properties:\n                        path:\n                          description: |-\n                            path that is exported by the NFS server.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the NFS export to be mounted with read-only permissions.\n                            Defaults to false.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                          type: boolean\n                        server:\n                          description: |-\n                            server is the hostname or IP address of the NFS server.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                          type: string\n                      required:\n                      - path\n                      - server\n                      type: object\n                    persistentVolumeClaim:\n                      description: |-\n                        persistentVolumeClaimVolumeSource represents a reference to a\n                        PersistentVolumeClaim in the same namespace.\n                        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims\n                      properties:\n                        claimName:\n                          description: |-\n                            claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume.\n                            More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly Will force the ReadOnly setting in VolumeMounts.\n                            Default false.\n                          type: boolean\n                      required:\n                      - claimName\n                      type: object\n                    photonPersistentDisk:\n                      description: |-\n                        photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine.\n                        Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        pdID:\n                          description: pdID is the ID that identifies Photon Controller persistent disk\n                          type: string\n                      required:\n                      - pdID\n                      type: object\n                    portworxVolume:\n                      description: |-\n                        portworxVolume represents a portworx volume attached and mounted on kubelets host machine.\n                        Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type\n                        are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate\n                        is on.\n                      properties:\n                        fsType:\n                          description: |-\n                            fSType represents the filesystem type to mount\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        volumeID:\n                          description: volumeID uniquely identifies a Portworx volume\n                          type: string\n                      required:\n                      - volumeID\n                      type: object\n                    projected:\n                      description: projected items for all in one resources secrets, configmaps, and downward API\n                      properties:\n                        defaultMode:\n                          description: |-\n                            defaultMode are the mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        sources:\n                          description: |-\n                            sources is the list of volume projections. Each entry in this list\n                            handles one source.\n                          items:\n                            description: |-\n                              Projection that may be projected along with other supported volume types.\n                              Exactly one of these fields must be set.\n                            properties:\n                              clusterTrustBundle:\n                                description: |-\n                                  ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field\n                                  of ClusterTrustBundle objects in an auto-updating file.\n\n                                  Alpha, gated by the ClusterTrustBundleProjection feature gate.\n\n                                  ClusterTrustBundle objects can either be selected by name, or by the\n                                  combination of signer name and a label selector.\n\n                                  Kubelet performs aggressive normalization of the PEM contents written\n                                  into the pod filesystem.  Esoteric PEM features such as inter-block\n                                  comments and block headers are stripped.  Certificates are deduplicated.\n                                  The ordering of certificates within the file is arbitrary, and Kubelet\n                                  may change the order over time.\n                                properties:\n                                  labelSelector:\n                                    description: |-\n                                      Select all ClusterTrustBundles that match this label selector.  Only has\n                                      effect if signerName is set.  Mutually-exclusive with name.  If unset,\n                                      interpreted as \"match nothing\".  If set but empty, interpreted as \"match\n                                      everything\".\n                                    properties:\n                                      matchExpressions:\n                                        description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                        items:\n                                          description: |-\n                                            A label selector requirement is a selector that contains values, a key, and an operator that\n                                            relates the key and values.\n                                          properties:\n                                            key:\n                                              description: key is the label key that the selector applies to.\n                                              type: string\n                                            operator:\n                                              description: |-\n                                                operator represents a key's relationship to a set of values.\n                                                Valid operators are In, NotIn, Exists and DoesNotExist.\n                                              type: string\n                                            values:\n                                              description: |-\n                                                values is an array of string values. If the operator is In or NotIn,\n                                                the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                                the values array must be empty. This array is replaced during a strategic\n                                                merge patch.\n                                              items:\n                                                type: string\n                                              type: array\n                                              x-kubernetes-list-type: atomic\n                                          required:\n                                          - key\n                                          - operator\n                                          type: object\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                      matchLabels:\n                                        additionalProperties:\n                                          type: string\n                                        description: |-\n                                          matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                          map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                          operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                        type: object\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  name:\n                                    description: |-\n                                      Select a single ClusterTrustBundle by object name.  Mutually-exclusive\n                                      with signerName and labelSelector.\n                                    type: string\n                                  optional:\n                                    description: |-\n                                      If true, don't block pod startup if the referenced ClusterTrustBundle(s)\n                                      aren't available.  If using name, then the named ClusterTrustBundle is\n                                      allowed not to exist.  If using signerName, then the combination of\n                                      signerName and labelSelector is allowed to match zero\n                                      ClusterTrustBundles.\n                                    type: boolean\n                                  path:\n                                    description: Relative path from the volume root to write the bundle.\n                                    type: string\n                                  signerName:\n                                    description: |-\n                                      Select all ClusterTrustBundles that match this signer name.\n                                      Mutually-exclusive with name.  The contents of all selected\n                                      ClusterTrustBundles will be unified and deduplicated.\n                                    type: string\n                                required:\n                                - path\n                                type: object\n                              configMap:\n                                description: configMap information about the configMap data to project\n                                properties:\n                                  items:\n                                    description: |-\n                                      items if unspecified, each key-value pair in the Data field of the referenced\n                                      ConfigMap will be projected into the volume as a file whose name is the\n                                      key and content is the value. If specified, the listed keys will be\n                                      projected into the specified paths, and unlisted keys will not be\n                                      present. If a key is specified which is not present in the ConfigMap,\n                                      the volume setup will error unless it is marked optional. Paths must be\n                                      relative and may not contain the '..' path or start with '..'.\n                                    items:\n                                      description: Maps a string key to a path within a volume.\n                                      properties:\n                                        key:\n                                          description: key is the key to project.\n                                          type: string\n                                        mode:\n                                          description: |-\n                                            mode is Optional: mode bits used to set permissions on this file.\n                                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                            If not specified, the volume defaultMode will be used.\n                                            This might be in conflict with other options that affect the file\n                                            mode, like fsGroup, and the result can be other mode bits set.\n                                          format: int32\n                                          type: integer\n                                        path:\n                                          description: |-\n                                            path is the relative path of the file to map the key to.\n                                            May not be an absolute path.\n                                            May not contain the path element '..'.\n                                            May not start with the string '..'.\n                                          type: string\n                                      required:\n                                      - key\n                                      - path\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: optional specify whether the ConfigMap or its keys must be defined\n                                    type: boolean\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              downwardAPI:\n                                description: downwardAPI information about the downwardAPI data to project\n                                properties:\n                                  items:\n                                    description: Items is a list of DownwardAPIVolume file\n                                    items:\n                                      description: DownwardAPIVolumeFile represents information to create the file containing the pod field\n                                      properties:\n                                        fieldRef:\n                                          description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.'\n                                          properties:\n                                            apiVersion:\n                                              description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                              type: string\n                                            fieldPath:\n                                              description: Path of the field to select in the specified API version.\n                                              type: string\n                                          required:\n                                          - fieldPath\n                                          type: object\n                                          x-kubernetes-map-type: atomic\n                                        mode:\n                                          description: |-\n                                            Optional: mode bits used to set permissions on this file, must be an octal value\n                                            between 0000 and 0777 or a decimal value between 0 and 511.\n                                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                            If not specified, the volume defaultMode will be used.\n                                            This might be in conflict with other options that affect the file\n                                            mode, like fsGroup, and the result can be other mode bits set.\n                                          format: int32\n                                          type: integer\n                                        path:\n                                          description: 'Required: Path is  the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..'''\n                                          type: string\n                                        resourceFieldRef:\n                                          description: |-\n                                            Selects a resource of the container: only resources limits and requests\n                                            (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.\n                                          properties:\n                                            containerName:\n                                              description: 'Container name: required for volumes, optional for env vars'\n                                              type: string\n                                            divisor:\n                                              anyOf:\n                                              - type: integer\n                                              - type: string\n                                              description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                              pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                              x-kubernetes-int-or-string: true\n                                            resource:\n                                              description: 'Required: resource to select'\n                                              type: string\n                                          required:\n                                          - resource\n                                          type: object\n                                          x-kubernetes-map-type: atomic\n                                      required:\n                                      - path\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                type: object\n                              secret:\n                                description: secret information about the secret data to project\n                                properties:\n                                  items:\n                                    description: |-\n                                      items if unspecified, each key-value pair in the Data field of the referenced\n                                      Secret will be projected into the volume as a file whose name is the\n                                      key and content is the value. If specified, the listed keys will be\n                                      projected into the specified paths, and unlisted keys will not be\n                                      present. If a key is specified which is not present in the Secret,\n                                      the volume setup will error unless it is marked optional. Paths must be\n                                      relative and may not contain the '..' path or start with '..'.\n                                    items:\n                                      description: Maps a string key to a path within a volume.\n                                      properties:\n                                        key:\n                                          description: key is the key to project.\n                                          type: string\n                                        mode:\n                                          description: |-\n                                            mode is Optional: mode bits used to set permissions on this file.\n                                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                            If not specified, the volume defaultMode will be used.\n                                            This might be in conflict with other options that affect the file\n                                            mode, like fsGroup, and the result can be other mode bits set.\n                                          format: int32\n                                          type: integer\n                                        path:\n                                          description: |-\n                                            path is the relative path of the file to map the key to.\n                                            May not be an absolute path.\n                                            May not contain the path element '..'.\n                                            May not start with the string '..'.\n                                          type: string\n                                      required:\n                                      - key\n                                      - path\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: optional field specify whether the Secret or its key must be defined\n                                    type: boolean\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              serviceAccountToken:\n                                description: serviceAccountToken is information about the serviceAccountToken data to project\n                                properties:\n                                  audience:\n                                    description: |-\n                                      audience is the intended audience of the token. A recipient of a token\n                                      must identify itself with an identifier specified in the audience of the\n                                      token, and otherwise should reject the token. The audience defaults to the\n                                      identifier of the apiserver.\n                                    type: string\n                                  expirationSeconds:\n                                    description: |-\n                                      expirationSeconds is the requested duration of validity of the service\n                                      account token. As the token approaches expiration, the kubelet volume\n                                      plugin will proactively rotate the service account token. The kubelet will\n                                      start trying to rotate the token if the token is older than 80 percent of\n                                      its time to live or if the token is older than 24 hours.Defaults to 1 hour\n                                      and must be at least 10 minutes.\n                                    format: int64\n                                    type: integer\n                                  path:\n                                    description: |-\n                                      path is the path relative to the mount point of the file to project the\n                                      token into.\n                                    type: string\n                                required:\n                                - path\n                                type: object\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    quobyte:\n                      description: |-\n                        quobyte represents a Quobyte mount on the host that shares a pod's lifetime.\n                        Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported.\n                      properties:\n                        group:\n                          description: |-\n                            group to map volume access to\n                            Default is no group\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the Quobyte volume to be mounted with read-only permissions.\n                            Defaults to false.\n                          type: boolean\n                        registry:\n                          description: |-\n                            registry represents a single or multiple Quobyte Registry services\n                            specified as a string as host:port pair (multiple entries are separated with commas)\n                            which acts as the central registry for volumes\n                          type: string\n                        tenant:\n                          description: |-\n                            tenant owning the given Quobyte volume in the Backend\n                            Used with dynamically provisioned Quobyte volumes, value is set by the plugin\n                          type: string\n                        user:\n                          description: |-\n                            user to map volume access to\n                            Defaults to serivceaccount user\n                          type: string\n                        volume:\n                          description: volume is a string that references an already created Quobyte volume by name.\n                          type: string\n                      required:\n                      - registry\n                      - volume\n                      type: object\n                    rbd:\n                      description: |-\n                        rbd represents a Rados Block Device mount on the host that shares a pod's lifetime.\n                        Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported.\n                        More info: https://examples.k8s.io/volumes/rbd/README.md\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd\n                          type: string\n                        image:\n                          description: |-\n                            image is the rados image name.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                        keyring:\n                          default: /etc/ceph/keyring\n                          description: |-\n                            keyring is the path to key ring for RBDUser.\n                            Default is /etc/ceph/keyring.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                        monitors:\n                          description: |-\n                            monitors is a collection of Ceph monitors.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        pool:\n                          default: rbd\n                          description: |-\n                            pool is the rados pool name.\n                            Default is rbd.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the ReadOnly setting in VolumeMounts.\n                            Defaults to false.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef is name of the authentication secret for RBDUser. If provided\n                            overrides keyring.\n                            Default is nil.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        user:\n                          default: admin\n                          description: |-\n                            user is the rados user name.\n                            Default is admin.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                      required:\n                      - image\n                      - monitors\n                      type: object\n                    scaleIO:\n                      description: |-\n                        scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.\n                        Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported.\n                      properties:\n                        fsType:\n                          default: xfs\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\".\n                            Default is \"xfs\".\n                          type: string\n                        gateway:\n                          description: gateway is the host address of the ScaleIO API Gateway.\n                          type: string\n                        protectionDomain:\n                          description: protectionDomain is the name of the ScaleIO Protection Domain for the configured storage.\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef references to the secret for ScaleIO user and other\n                            sensitive information. If this is not provided, Login operation will fail.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        sslEnabled:\n                          description: sslEnabled Flag enable/disable SSL communication with Gateway, default false\n                          type: boolean\n                        storageMode:\n                          default: ThinProvisioned\n                          description: |-\n                            storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.\n                            Default is ThinProvisioned.\n                          type: string\n                        storagePool:\n                          description: storagePool is the ScaleIO Storage Pool associated with the protection domain.\n                          type: string\n                        system:\n                          description: system is the name of the storage system as configured in ScaleIO.\n                          type: string\n                        volumeName:\n                          description: |-\n                            volumeName is the name of a volume already created in the ScaleIO system\n                            that is associated with this volume source.\n                          type: string\n                      required:\n                      - gateway\n                      - secretRef\n                      - system\n                      type: object\n                    secret:\n                      description: |-\n                        secret represents a secret that should populate this volume.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#secret\n                      properties:\n                        defaultMode:\n                          description: |-\n                            defaultMode is Optional: mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values\n                            for mode bits. Defaults to 0644.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        items:\n                          description: |-\n                            items If unspecified, each key-value pair in the Data field of the referenced\n                            Secret will be projected into the volume as a file whose name is the\n                            key and content is the value. If specified, the listed keys will be\n                            projected into the specified paths, and unlisted keys will not be\n                            present. If a key is specified which is not present in the Secret,\n                            the volume setup will error unless it is marked optional. Paths must be\n                            relative and may not contain the '..' path or start with '..'.\n                          items:\n                            description: Maps a string key to a path within a volume.\n                            properties:\n                              key:\n                                description: key is the key to project.\n                                type: string\n                              mode:\n                                description: |-\n                                  mode is Optional: mode bits used to set permissions on this file.\n                                  Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                  YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                  If not specified, the volume defaultMode will be used.\n                                  This might be in conflict with other options that affect the file\n                                  mode, like fsGroup, and the result can be other mode bits set.\n                                format: int32\n                                type: integer\n                              path:\n                                description: |-\n                                  path is the relative path of the file to map the key to.\n                                  May not be an absolute path.\n                                  May not contain the path element '..'.\n                                  May not start with the string '..'.\n                                type: string\n                            required:\n                            - key\n                            - path\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        optional:\n                          description: optional field specify whether the Secret or its keys must be defined\n                          type: boolean\n                        secretName:\n                          description: |-\n                            secretName is the name of the secret in the pod's namespace to use.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#secret\n                          type: string\n                      type: object\n                    storageos:\n                      description: |-\n                        storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes.\n                        Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef specifies the secret to use for obtaining the StorageOS API\n                            credentials.  If not specified, default values will be attempted.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        volumeName:\n                          description: |-\n                            volumeName is the human-readable name of the StorageOS volume.  Volume\n                            names are only unique within a namespace.\n                          type: string\n                        volumeNamespace:\n                          description: |-\n                            volumeNamespace specifies the scope of the volume within StorageOS.  If no\n                            namespace is specified then the Pod's namespace will be used.  This allows the\n                            Kubernetes name scoping to be mirrored within StorageOS for tighter integration.\n                            Set VolumeName to any name to override the default behaviour.\n                            Set to \"default\" if you are not using namespaces within StorageOS.\n                            Namespaces that do not pre-exist within StorageOS will be created.\n                          type: string\n                      type: object\n                    vsphereVolume:\n                      description: |-\n                        vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine.\n                        Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type\n                        are redirected to the csi.vsphere.vmware.com CSI driver.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        storagePolicyID:\n                          description: storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName.\n                          type: string\n                        storagePolicyName:\n                          description: storagePolicyName is the storage Policy Based Management (SPBM) profile name.\n                          type: string\n                        volumePath:\n                          description: volumePath is the path that identifies vSphere volume vmdk\n                          type: string\n                      required:\n                      - volumePath\n                      type: object\n                  required:\n                  - name\n                  type: object\n                type: array\n              walCompression:\n                description: |-\n                  Configures compression of the write-ahead log (WAL) using Snappy.\n\n                  WAL compression is enabled by default for Prometheus >= 2.20.0\n\n                  Requires Prometheus v2.11.0 and above.\n                type: boolean\n              web:\n                description: Defines the configuration of the Prometheus web server.\n                properties:\n                  httpConfig:\n                    description: Defines HTTP parameters for web server.\n                    properties:\n                      headers:\n                        description: List of headers that can be added to HTTP responses.\n                        properties:\n                          contentSecurityPolicy:\n                            description: |-\n                              Set the Content-Security-Policy header to HTTP responses.\n                              Unset if blank.\n                            type: string\n                          strictTransportSecurity:\n                            description: |-\n                              Set the Strict-Transport-Security header to HTTP responses.\n                              Unset if blank.\n                              Please make sure that you use this with care as this header might force\n                              browsers to load Prometheus and the other applications hosted on the same\n                              domain and subdomains over HTTPS.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security\n                            type: string\n                          xContentTypeOptions:\n                            description: |-\n                              Set the X-Content-Type-Options header to HTTP responses.\n                              Unset if blank. Accepted value is nosniff.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n                            enum:\n                            - \"\"\n                            - NoSniff\n                            type: string\n                          xFrameOptions:\n                            description: |-\n                              Set the X-Frame-Options header to HTTP responses.\n                              Unset if blank. Accepted values are deny and sameorigin.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n                            enum:\n                            - \"\"\n                            - Deny\n                            - SameOrigin\n                            type: string\n                          xXSSProtection:\n                            description: |-\n                              Set the X-XSS-Protection header to all responses.\n                              Unset if blank.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n                            type: string\n                        type: object\n                      http2:\n                        description: |-\n                          Enable HTTP/2 support. Note that HTTP/2 is only supported with TLS.\n                          When TLSConfig is not configured, HTTP/2 will be disabled.\n                          Whenever the value of the field changes, a rolling update will be triggered.\n                        type: boolean\n                    type: object\n                  maxConnections:\n                    description: |-\n                      Defines the maximum number of simultaneous connections\n                      A zero value means that Prometheus doesn't accept any incoming connection.\n                    format: int32\n                    minimum: 0\n                    type: integer\n                  pageTitle:\n                    description: The prometheus web page title.\n                    type: string\n                  tlsConfig:\n                    description: Defines the TLS parameters for HTTPS.\n                    properties:\n                      cert:\n                        description: |-\n                          Secret or ConfigMap containing the TLS certificate for the web server.\n\n                          Either `keySecret` or `keyFile` must be defined.\n\n                          It is mutually exclusive with `certFile`.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      certFile:\n                        description: |-\n                          Path to the TLS certificate file in the container for the web server.\n\n                          Either `keySecret` or `keyFile` must be defined.\n\n                          It is mutually exclusive with `cert`.\n                        type: string\n                      cipherSuites:\n                        description: |-\n                          List of supported cipher suites for TLS versions up to TLS 1.2.\n\n                          If not defined, the Go default cipher suites are used.\n                          Available cipher suites are documented in the Go documentation:\n                          https://golang.org/pkg/crypto/tls/#pkg-constants\n                        items:\n                          type: string\n                        type: array\n                      client_ca:\n                        description: |-\n                          Secret or ConfigMap containing the CA certificate for client certificate\n                          authentication to the server.\n\n                          It is mutually exclusive with `clientCAFile`.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      clientAuthType:\n                        description: |-\n                          The server policy for client TLS authentication.\n\n                          For more detail on clientAuth options:\n                          https://golang.org/pkg/crypto/tls/#ClientAuthType\n                        type: string\n                      clientCAFile:\n                        description: |-\n                          Path to the CA certificate file for client certificate authentication to\n                          the server.\n\n                          It is mutually exclusive with `client_ca`.\n                        type: string\n                      curvePreferences:\n                        description: |-\n                          Elliptic curves that will be used in an ECDHE handshake, in preference\n                          order.\n\n                          Available curves are documented in the Go documentation:\n                          https://golang.org/pkg/crypto/tls/#CurveID\n                        items:\n                          type: string\n                        type: array\n                      keyFile:\n                        description: |-\n                          Path to the TLS private key file in the container for the web server.\n\n                          If defined, either `cert` or `certFile` must be defined.\n\n                          It is mutually exclusive with `keySecret`.\n                        type: string\n                      keySecret:\n                        description: |-\n                          Secret containing the TLS private key for the web server.\n\n                          Either `cert` or `certFile` must be defined.\n\n                          It is mutually exclusive with `keyFile`.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: Maximum TLS version that is acceptable.\n                        type: string\n                      minVersion:\n                        description: Minimum TLS version that is acceptable.\n                        type: string\n                      preferServerCipherSuites:\n                        description: |-\n                          Controls whether the server selects the client's most preferred cipher\n                          suite, or the server's most preferred cipher suite.\n\n                          If true then the server's preference, as expressed in\n                          the order of elements in cipherSuites, is used.\n                        type: boolean\n                    type: object\n                type: object\n            type: object\n            x-kubernetes-validations:\n            - message: replicas cannot be set when mode is DaemonSet\n              rule: '!(has(self.mode) && self.mode == ''DaemonSet'' && has(self.replicas))'\n            - message: storage cannot be set when mode is DaemonSet\n              rule: '!(has(self.mode) && self.mode == ''DaemonSet'' && has(self.storage))'\n            - message: shards cannot be greater than 1 when mode is DaemonSet\n              rule: '!(has(self.mode) && self.mode == ''DaemonSet'' && has(self.shards) && self.shards > 1)'\n            - message: persistentVolumeClaimRetentionPolicy cannot be set when mode is DaemonSet\n              rule: '!(has(self.mode) && self.mode == ''DaemonSet'' && has(self.persistentVolumeClaimRetentionPolicy))'\n            - message: scrapeConfigSelector cannot be set when mode is DaemonSet\n              rule: '!(has(self.mode) && self.mode == ''DaemonSet'' && has(self.scrapeConfigSelector))'\n            - message: probeSelector cannot be set when mode is DaemonSet\n              rule: '!(has(self.mode) && self.mode == ''DaemonSet'' && has(self.probeSelector))'\n          status:\n            description: |-\n              Most recent observed status of the Prometheus cluster. Read-only.\n              More info:\n              https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n            properties:\n              availableReplicas:\n                description: |-\n                  Total number of available pods (ready for at least minReadySeconds)\n                  targeted by this Prometheus deployment.\n                format: int32\n                type: integer\n              conditions:\n                description: The current state of the Prometheus deployment.\n                items:\n                  description: |-\n                    Condition represents the state of the resources associated with the\n                    Prometheus, Alertmanager or ThanosRuler resource.\n                  properties:\n                    lastTransitionTime:\n                      description: lastTransitionTime is the time of the last update to the current status property.\n                      format: date-time\n                      type: string\n                    message:\n                      description: Human-readable message indicating details for the condition's last transition.\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        ObservedGeneration represents the .metadata.generation that the\n                        condition was set based upon. For instance, if `.metadata.generation` is\n                        currently 12, but the `.status.conditions[].observedGeneration` is 9, the\n                        condition is out of date with respect to the current state of the\n                        instance.\n                      format: int64\n                      type: integer\n                    reason:\n                      description: Reason for the condition's last transition.\n                      type: string\n                    status:\n                      description: Status of the condition.\n                      minLength: 1\n                      type: string\n                    type:\n                      description: Type of the condition being reported.\n                      minLength: 1\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - status\n                  - type\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              paused:\n                description: |-\n                  Represents whether any actions on the underlying managed objects are\n                  being performed. Only delete actions will be performed.\n                type: boolean\n              replicas:\n                description: |-\n                  Total number of non-terminated pods targeted by this Prometheus deployment\n                  (their labels match the selector).\n                format: int32\n                type: integer\n              selector:\n                description: The selector used to match the pods targeted by this Prometheus resource.\n                type: string\n              shardStatuses:\n                description: The list has one entry per shard. Each entry provides a summary of the shard status.\n                items:\n                  properties:\n                    availableReplicas:\n                      description: |-\n                        Total number of available pods (ready for at least minReadySeconds)\n                        targeted by this shard.\n                      format: int32\n                      type: integer\n                    replicas:\n                      description: Total number of pods targeted by this shard.\n                      format: int32\n                      type: integer\n                    shardID:\n                      description: Identifier of the shard.\n                      type: string\n                    unavailableReplicas:\n                      description: Total number of unavailable pods targeted by this shard.\n                      format: int32\n                      type: integer\n                    updatedReplicas:\n                      description: |-\n                        Total number of non-terminated pods targeted by this shard\n                        that have the desired spec.\n                      format: int32\n                      type: integer\n                  required:\n                  - availableReplicas\n                  - replicas\n                  - shardID\n                  - unavailableReplicas\n                  - updatedReplicas\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - shardID\n                x-kubernetes-list-type: map\n              shards:\n                description: Shards is the most recently observed number of shards.\n                format: int32\n                type: integer\n              unavailableReplicas:\n                description: Total number of unavailable pods targeted by this Prometheus deployment.\n                format: int32\n                type: integer\n              updatedReplicas:\n                description: |-\n                  Total number of non-terminated pods targeted by this Prometheus deployment\n                  that have the desired version spec.\n                format: int32\n                type: integer\n            required:\n            - availableReplicas\n            - paused\n            - replicas\n            - unavailableReplicas\n            - updatedReplicas\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      scale:\n        labelSelectorPath: .status.selector\n        specReplicasPath: .spec.shards\n        statusReplicasPath: .status.shards\n      status: {}\n"
  },
  {
    "path": "hack/config/monitoring/crds/0prometheusruleCustomResourceDefinition.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.18.0\n    operator.prometheus.io/version: 0.85.0\n  name: prometheusrules.monitoring.coreos.com\nspec:\n  group: monitoring.coreos.com\n  names:\n    categories:\n    - prometheus-operator\n    kind: PrometheusRule\n    listKind: PrometheusRuleList\n    plural: prometheusrules\n    shortNames:\n    - promrule\n    singular: prometheusrule\n  scope: Namespaced\n  versions:\n  - name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The `PrometheusRule` custom resource definition (CRD) defines [alerting](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) and [recording](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) rules to be evaluated by `Prometheus` or `ThanosRuler` objects.\n\n          `Prometheus` and `ThanosRuler` objects select `PrometheusRule` objects using label and namespace selectors.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Specification of desired alerting rule definitions for Prometheus.\n            properties:\n              groups:\n                description: Content of Prometheus rule file\n                items:\n                  description: RuleGroup is a list of sequentially evaluated recording and alerting rules.\n                  properties:\n                    interval:\n                      description: Interval determines how often rules in the group are evaluated.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    labels:\n                      additionalProperties:\n                        type: string\n                      description: |-\n                        Labels to add or overwrite before storing the result for its rules.\n                        The labels defined at the rule level take precedence.\n\n                        It requires Prometheus >= 3.0.0.\n                        The field is ignored for Thanos Ruler.\n                      type: object\n                    limit:\n                      description: |-\n                        Limit the number of alerts an alerting rule and series a recording\n                        rule can produce.\n                        Limit is supported starting with Prometheus >= 2.31 and Thanos Ruler >= 0.24.\n                      type: integer\n                    name:\n                      description: Name of the rule group.\n                      minLength: 1\n                      type: string\n                    partial_response_strategy:\n                      description: |-\n                        PartialResponseStrategy is only used by ThanosRuler and will\n                        be ignored by Prometheus instances.\n                        More info: https://github.com/thanos-io/thanos/blob/main/docs/components/rule.md#partial-response\n                      pattern: ^(?i)(abort|warn)?$\n                      type: string\n                    query_offset:\n                      description: |-\n                        Defines the offset the rule evaluation timestamp of this particular group by the specified duration into the past.\n\n                        It requires Prometheus >= v2.53.0.\n                        It is not supported for ThanosRuler.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    rules:\n                      description: List of alerting and recording rules.\n                      items:\n                        description: |-\n                          Rule describes an alerting or recording rule\n                          See Prometheus documentation: [alerting](https://www.prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) or [recording](https://www.prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules) rule\n                        properties:\n                          alert:\n                            description: |-\n                              Name of the alert. Must be a valid label value.\n                              Only one of `record` and `alert` must be set.\n                            type: string\n                          annotations:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              Annotations to add to each alert.\n                              Only valid for alerting rules.\n                            type: object\n                          expr:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            description: PromQL expression to evaluate.\n                            x-kubernetes-int-or-string: true\n                          for:\n                            description: Alerts are considered firing once they have been returned for this long.\n                            pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                            type: string\n                          keep_firing_for:\n                            description: KeepFiringFor defines how long an alert will continue firing after the condition that triggered it has cleared.\n                            minLength: 1\n                            pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                            type: string\n                          labels:\n                            additionalProperties:\n                              type: string\n                            description: Labels to add or overwrite.\n                            type: object\n                          record:\n                            description: |-\n                              Name of the time series to output to. Must be a valid metric name.\n                              Only one of `record` and `alert` must be set.\n                            type: string\n                        required:\n                        - expr\n                        type: object\n                      type: array\n                  required:\n                  - name\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - name\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n"
  },
  {
    "path": "hack/config/monitoring/crds/0scrapeconfigCustomResourceDefinition.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.18.0\n    operator.prometheus.io/version: 0.85.0\n  name: scrapeconfigs.monitoring.coreos.com\nspec:\n  group: monitoring.coreos.com\n  names:\n    categories:\n    - prometheus-operator\n    kind: ScrapeConfig\n    listKind: ScrapeConfigList\n    plural: scrapeconfigs\n    shortNames:\n    - scfg\n    singular: scrapeconfig\n  scope: Namespaced\n  versions:\n  - name: v1alpha1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          ScrapeConfig defines a namespaced Prometheus scrape_config to be aggregated across\n          multiple namespaces into the Prometheus configuration.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: ScrapeConfigSpec is a specification of the desired configuration for a scrape configuration.\n            properties:\n              authorization:\n                description: Authorization header to use on every scrape request.\n                properties:\n                  credentials:\n                    description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  type:\n                    description: |-\n                      Defines the authentication type. The value is case-insensitive.\n\n                      \"Basic\" is not a supported value.\n\n                      Default: \"Bearer\"\n                    type: string\n                type: object\n              azureSDConfigs:\n                description: AzureSDConfigs defines a list of Azure service discovery configurations.\n                items:\n                  description: |-\n                    AzureSDConfig allow retrieving scrape targets from Azure VMs.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#azure_sd_config\n                  properties:\n                    authenticationMethod:\n                      description: |-\n                        # The authentication method, either `OAuth` or `ManagedIdentity` or `SDK`.\n                        See https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview\n                        SDK authentication method uses environment variables by default.\n                        See https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication\n                      enum:\n                      - OAuth\n                      - ManagedIdentity\n                      - SDK\n                      type: string\n                    authorization:\n                      description: |-\n                        Authorization header configuration to authenticate against the target HTTP endpoint.\n                        Cannot be set at the same time as `oAuth2`, or `basicAuth`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: |-\n                        BasicAuth information to authenticate against the target HTTP endpoint.\n                        More info: https://prometheus.io/docs/operating/configuration/#endpoints\n                        Cannot be set at the same time as `authorization`, or `oAuth2`.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    clientID:\n                      description: Optional client ID. Only required with the OAuth authentication method.\n                      minLength: 1\n                      type: string\n                    clientSecret:\n                      description: Optional client secret. Only required with the OAuth authentication method.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    environment:\n                      description: The Azure environment.\n                      minLength: 1\n                      type: string\n                    followRedirects:\n                      description: Configure whether HTTP requests follow HTTP 3xx redirects.\n                      type: boolean\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth 2.0 configuration to authenticate against the target HTTP endpoint.\n                        Cannot be set at the same time as `authorization`, or `basicAuth`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    port:\n                      description: |-\n                        The port to scrape metrics from. If using the public IP address, this must\n                        instead be specified in the relabeling rule.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: RefreshInterval configures the refresh interval at which Prometheus will re-read the instance list.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    resourceGroup:\n                      description: |-\n                        Optional resource group name. Limits discovery to this resource group.\n                        Requires  Prometheus v2.35.0 and above\n                      minLength: 1\n                      type: string\n                    subscriptionID:\n                      description: The subscription ID. Always required.\n                      minLength: 1\n                      type: string\n                    tenantID:\n                      description: Optional tenant ID. Only required with the OAuth authentication method.\n                      minLength: 1\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration applying to the target HTTP endpoint.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  required:\n                  - subscriptionID\n                  type: object\n                type: array\n              basicAuth:\n                description: BasicAuth information to use on every scrape request.\n                properties:\n                  password:\n                    description: |-\n                      `password` specifies a key of a Secret containing the password for\n                      authentication.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  username:\n                    description: |-\n                      `username` specifies a key of a Secret containing the username for\n                      authentication.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                type: object\n              consulSDConfigs:\n                description: ConsulSDConfigs defines a list of Consul service discovery configurations.\n                items:\n                  description: |-\n                    ConsulSDConfig defines a Consul service discovery configuration\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#consul_sd_config\n                  properties:\n                    allowStale:\n                      description: |-\n                        Allow stale Consul results (see https://www.consul.io/api/features/consistency.html). Will reduce load on Consul.\n                        If unset, Prometheus uses its default value.\n                      type: boolean\n                    authorization:\n                      description: |-\n                        Optional Authorization header configuration to authenticate against the Consul Server.\n                        Cannot be set at the same time as `basicAuth`, or `oauth2`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: |-\n                        Optional BasicAuth information to authenticate against the Consul Server.\n                        More info: https://prometheus.io/docs/operating/configuration/#endpoints\n                        Cannot be set at the same time as `authorization`, or `oauth2`.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    datacenter:\n                      description: Consul Datacenter name, if not provided it will use the local Consul Agent Datacenter.\n                      minLength: 1\n                      type: string\n                    enableHTTP2:\n                      description: |-\n                        Whether to enable HTTP2.\n                        If unset, Prometheus uses its default value.\n                      type: boolean\n                    filter:\n                      description: |-\n                        Filter expression used to filter the catalog results.\n                        See https://www.consul.io/api-docs/catalog#list-services\n                        It requires Prometheus >= 3.0.0.\n                      minLength: 1\n                      type: string\n                    followRedirects:\n                      description: |-\n                        Configure whether HTTP requests follow HTTP 3xx redirects.\n                        If unset, Prometheus uses its default value.\n                      type: boolean\n                    namespace:\n                      description: |-\n                        Namespaces are only supported in Consul Enterprise.\n\n                        It requires Prometheus >= 2.28.0.\n                      minLength: 1\n                      type: string\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    nodeMeta:\n                      additionalProperties:\n                        type: string\n                      description: |-\n                        Node metadata key/value pairs to filter nodes for a given service.\n                        Starting with Consul 1.14, it is recommended to use `filter` with the `NodeMeta` selector instead.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    oauth2:\n                      description: |-\n                        Optional OAuth2.0 configuration.\n                        Cannot be set at the same time as `basicAuth`, or `authorization`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    partition:\n                      description: Admin Partitions are only supported in Consul Enterprise.\n                      minLength: 1\n                      type: string\n                    pathPrefix:\n                      description: |-\n                        Prefix for URIs for when consul is behind an API gateway (reverse proxy).\n\n                        It requires Prometheus >= 2.45.0.\n                      minLength: 1\n                      type: string\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: |-\n                        The time after which the provided names are refreshed.\n                        On large setup it might be a good idea to increase this value because the catalog will change all the time.\n                        If unset, Prometheus uses its default value.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    scheme:\n                      description: HTTP Scheme default \"http\"\n                      enum:\n                      - HTTP\n                      - HTTPS\n                      type: string\n                    server:\n                      description: Consul server address. A valid string consisting of a hostname or IP followed by an optional port number.\n                      minLength: 1\n                      type: string\n                    services:\n                      description: A list of services for which targets are retrieved. If omitted, all services are scraped.\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: set\n                    tagSeparator:\n                      description: |-\n                        The string by which Consul tags are joined into the tag label.\n                        If unset, Prometheus uses its default value.\n                      minLength: 1\n                      type: string\n                    tags:\n                      description: |-\n                        An optional list of tags used to filter nodes for a given service. Services must contain all tags in the list.\n                        Starting with Consul 1.14, it is recommended to use `filter` with the `ServiceTags` selector instead.\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: set\n                    tlsConfig:\n                      description: TLS configuration to connect to the Consul API.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                    tokenRef:\n                      description: Consul ACL TokenRef, if not provided it will use the ACL from the local Consul Agent.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                  required:\n                  - server\n                  type: object\n                type: array\n              convertClassicHistogramsToNHCB:\n                description: |-\n                  Whether to convert all scraped classic histograms into a native histogram with custom buckets.\n                  It requires Prometheus >= v3.0.0.\n                type: boolean\n              digitalOceanSDConfigs:\n                description: DigitalOceanSDConfigs defines a list of DigitalOcean service discovery configurations.\n                items:\n                  description: |-\n                    DigitalOceanSDConfig allow retrieving scrape targets from DigitalOcean's Droplets API.\n                    This service discovery uses the public IPv4 address by default, by that can be changed with relabeling\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#digitalocean_sd_config\n                  properties:\n                    authorization:\n                      description: |-\n                        Authorization header configuration to authenticate against the DigitalOcean API.\n                        Cannot be set at the same time as `oauth2`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: Configure whether HTTP requests follow HTTP 3xx redirects.\n                      type: boolean\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth 2.0 configuration.\n                        Cannot be set at the same time as `authorization`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    port:\n                      description: The port to scrape metrics from.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: Refresh interval to re-read the instance list.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration applying to the target HTTP endpoint.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  type: object\n                type: array\n              dnsSDConfigs:\n                description: DNSSDConfigs defines a list of DNS service discovery configurations.\n                items:\n                  description: |-\n                    DNSSDConfig allows specifying a set of DNS domain names which are periodically queried to discover a list of targets.\n                    The DNS servers to be contacted are read from /etc/resolv.conf.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#dns_sd_config\n                  properties:\n                    names:\n                      description: A list of DNS domain names to be queried.\n                      items:\n                        minLength: 1\n                        type: string\n                      minItems: 1\n                      type: array\n                    port:\n                      description: |-\n                        The port number used if the query type is not SRV\n                        Ignored for SRV records\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    refreshInterval:\n                      description: |-\n                        RefreshInterval configures the time after which the provided names are refreshed.\n                        If not set, Prometheus uses its default value.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    type:\n                      description: |-\n                        The type of DNS query to perform. One of SRV, A, AAAA, MX or NS.\n                        If not set, Prometheus uses its default value.\n\n                        When set to NS, it requires Prometheus >= v2.49.0.\n                        When set to MX, it requires Prometheus >= v2.38.0\n                      enum:\n                      - A\n                      - AAAA\n                      - MX\n                      - NS\n                      - SRV\n                      type: string\n                  required:\n                  - names\n                  type: object\n                type: array\n              dockerSDConfigs:\n                description: DockerSDConfigs defines a list of Docker service discovery configurations.\n                items:\n                  description: |-\n                    Docker SD configurations allow retrieving scrape targets from Docker Engine hosts.\n                    This SD discovers \"containers\" and will create a target for each network IP and\n                    port the container is configured to expose.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#docker_sd_config\n                  properties:\n                    authorization:\n                      description: |-\n                        Authorization header configuration to authenticate against the Docker API.\n                        Cannot be set at the same time as `oauth2`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: BasicAuth information to use on every scrape request.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    filters:\n                      description: Optional filters to limit the discovery process to a subset of the available resources.\n                      items:\n                        description: Filter name and value pairs to limit the discovery process to a subset of available resources.\n                        properties:\n                          name:\n                            description: Name of the Filter.\n                            type: string\n                          values:\n                            description: Value to filter on.\n                            items:\n                              minLength: 1\n                              type: string\n                            minItems: 1\n                            type: array\n                            x-kubernetes-list-type: set\n                        required:\n                        - name\n                        - values\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - name\n                      x-kubernetes-list-type: map\n                    followRedirects:\n                      description: Configure whether HTTP requests follow HTTP 3xx redirects.\n                      type: boolean\n                    host:\n                      description: Address of the docker daemon\n                      minLength: 1\n                      type: string\n                    hostNetworkingHost:\n                      description: The host to use if the container is in host networking mode.\n                      minLength: 1\n                      type: string\n                    matchFirstNetwork:\n                      description: |-\n                        Configure whether to match the first network if the container has multiple networks defined.\n                        If unset, Prometheus uses true by default.\n                        It requires Prometheus >= v2.54.1.\n                      type: boolean\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth 2.0 configuration.\n                        Cannot be set at the same time as `authorization`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    port:\n                      description: The port to scrape metrics from.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: Time after which the container is refreshed.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration applying to the target HTTP endpoint.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  required:\n                  - host\n                  type: object\n                type: array\n              dockerSwarmSDConfigs:\n                description: DockerswarmSDConfigs defines a list of Dockerswarm service discovery configurations.\n                items:\n                  description: |-\n                    DockerSwarmSDConfig configurations allow retrieving scrape targets from Docker Swarm engine.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#dockerswarm_sd_config\n                  properties:\n                    authorization:\n                      description: Authorization header configuration to authenticate against the target HTTP endpoint.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: Optional HTTP basic authentication information.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    filters:\n                      description: |-\n                        Optional filters to limit the discovery process to a subset of available\n                        resources.\n                        The available filters are listed in the upstream documentation:\n                        Services: https://docs.docker.com/engine/api/v1.40/#operation/ServiceList\n                        Tasks: https://docs.docker.com/engine/api/v1.40/#operation/TaskList\n                        Nodes: https://docs.docker.com/engine/api/v1.40/#operation/NodeList\n                      items:\n                        description: Filter name and value pairs to limit the discovery process to a subset of available resources.\n                        properties:\n                          name:\n                            description: Name of the Filter.\n                            type: string\n                          values:\n                            description: Value to filter on.\n                            items:\n                              minLength: 1\n                              type: string\n                            minItems: 1\n                            type: array\n                            x-kubernetes-list-type: set\n                        required:\n                        - name\n                        - values\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - name\n                      x-kubernetes-list-type: map\n                    followRedirects:\n                      description: Configure whether HTTP requests follow HTTP 3xx redirects.\n                      type: boolean\n                    host:\n                      description: Address of the Docker daemon\n                      pattern: ^[a-zA-Z][a-zA-Z0-9+.-]*://.+$\n                      type: string\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth 2.0 configuration.\n                        Cannot be set at the same time as `authorization`, or `basicAuth`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    port:\n                      description: |-\n                        The port to scrape metrics from, when `role` is nodes, and for discovered\n                        tasks and services that don't have published ports.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: The time after which the service discovery data is refreshed.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    role:\n                      description: Role of the targets to retrieve. Must be `Services`, `Tasks`, or `Nodes`.\n                      enum:\n                      - Services\n                      - Tasks\n                      - Nodes\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration to use on every scrape request\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  required:\n                  - host\n                  - role\n                  type: object\n                type: array\n              ec2SDConfigs:\n                description: EC2SDConfigs defines a list of EC2 service discovery configurations.\n                items:\n                  description: |-\n                    EC2SDConfig allow retrieving scrape targets from AWS EC2 instances.\n                    The private IP address is used by default, but may be changed to the public IP address with relabeling.\n                    The IAM credentials used must have the ec2:DescribeInstances permission to discover scrape targets\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#ec2_sd_config\n\n                    The EC2 service discovery requires AWS API keys or role ARN for authentication.\n                    BasicAuth, Authorization and OAuth2 fields are not present on purpose.\n                  properties:\n                    accessKey:\n                      description: AccessKey is the AWS API key.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    enableHTTP2:\n                      description: |-\n                        Whether to enable HTTP2.\n                        It requires Prometheus >= v2.41.0\n                      type: boolean\n                    filters:\n                      description: |-\n                        Filters can be used optionally to filter the instance list by other criteria.\n                        Available filter criteria can be found here:\n                        https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html\n                        Filter API documentation: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_Filter.html\n                        It requires Prometheus >= v2.3.0\n                      items:\n                        description: Filter name and value pairs to limit the discovery process to a subset of available resources.\n                        properties:\n                          name:\n                            description: Name of the Filter.\n                            type: string\n                          values:\n                            description: Value to filter on.\n                            items:\n                              minLength: 1\n                              type: string\n                            minItems: 1\n                            type: array\n                            x-kubernetes-list-type: set\n                        required:\n                        - name\n                        - values\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - name\n                      x-kubernetes-list-type: map\n                    followRedirects:\n                      description: |-\n                        Configure whether HTTP requests follow HTTP 3xx redirects.\n                        It requires Prometheus >= v2.41.0\n                      type: boolean\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    port:\n                      description: |-\n                        The port to scrape metrics from. If using the public IP address, this must\n                        instead be specified in the relabeling rule.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: RefreshInterval configures the refresh interval at which Prometheus will re-read the instance list.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    region:\n                      description: The AWS region.\n                      minLength: 1\n                      type: string\n                    roleARN:\n                      description: AWS Role ARN, an alternative to using AWS API keys.\n                      minLength: 1\n                      type: string\n                    secretKey:\n                      description: SecretKey is the AWS API secret.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    tlsConfig:\n                      description: |-\n                        TLS configuration to connect to the AWS EC2 API.\n                        It requires Prometheus >= v2.41.0\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  type: object\n                type: array\n              enableCompression:\n                description: |-\n                  When false, Prometheus will request uncompressed response from the scraped target.\n\n                  It requires Prometheus >= v2.49.0.\n\n                  If unset, Prometheus uses true by default.\n                type: boolean\n              enableHTTP2:\n                description: Whether to enable HTTP2.\n                type: boolean\n              eurekaSDConfigs:\n                description: EurekaSDConfigs defines a list of Eureka service discovery configurations.\n                items:\n                  description: |-\n                    Eureka SD configurations allow retrieving scrape targets using the Eureka REST API.\n                    Prometheus will periodically check the REST endpoint and create a target for every app instance.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#eureka_sd_config\n                  properties:\n                    authorization:\n                      description: Authorization header to use on every scrape request.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: BasicAuth information to use on every scrape request.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: Configure whether HTTP requests follow HTTP 3xx redirects.\n                      type: boolean\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth 2.0 configuration.\n                        Cannot be set at the same time as `authorization` or `basic_auth`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: Refresh interval to re-read the instance list.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    server:\n                      description: The URL to connect to the Eureka server.\n                      minLength: 1\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration applying to the target HTTP endpoint.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  required:\n                  - server\n                  type: object\n                type: array\n              fallbackScrapeProtocol:\n                description: |-\n                  The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type.\n\n                  It requires Prometheus >= v3.0.0.\n                enum:\n                - PrometheusProto\n                - OpenMetricsText0.0.1\n                - OpenMetricsText1.0.0\n                - PrometheusText0.0.4\n                - PrometheusText1.0.0\n                type: string\n              fileSDConfigs:\n                description: FileSDConfigs defines a list of file service discovery configurations.\n                items:\n                  description: |-\n                    FileSDConfig defines a Prometheus file service discovery configuration\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#file_sd_config\n                  properties:\n                    files:\n                      description: |-\n                        List of files to be used for file discovery. Recommendation: use absolute paths. While relative paths work, the\n                        prometheus-operator project makes no guarantees about the working directory where the configuration file is\n                        stored.\n                        Files must be mounted using Prometheus.ConfigMaps or Prometheus.Secrets.\n                      items:\n                        description: SDFile represents a file used for service discovery\n                        pattern: ^[^*]*(\\*[^/]*)?\\.(json|yml|yaml|JSON|YML|YAML)$\n                        type: string\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-type: set\n                    refreshInterval:\n                      description: RefreshInterval configures the refresh interval at which Prometheus will reload the content of the files.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                  required:\n                  - files\n                  type: object\n                type: array\n              gceSDConfigs:\n                description: GCESDConfigs defines a list of GCE service discovery configurations.\n                items:\n                  description: |-\n                    GCESDConfig configures scrape targets from GCP GCE instances.\n                    The private IP address is used by default, but may be changed to\n                    the public IP address with relabeling.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#gce_sd_config\n\n                    The GCE service discovery will load the Google Cloud credentials\n                    from the file specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable.\n                    See https://cloud.google.com/kubernetes-engine/docs/tutorials/authenticating-to-cloud-platform\n\n                    A pre-requisite for using GCESDConfig is that a Secret containing valid\n                    Google Cloud credentials is mounted into the Prometheus or PrometheusAgent\n                    pod via the `.spec.secrets` field and that the GOOGLE_APPLICATION_CREDENTIALS\n                    environment variable is set to /etc/prometheus/secrets/<secret-name>/<credentials-filename.json>.\n                  properties:\n                    filter:\n                      description: |-\n                        Filter can be used optionally to filter the instance list by other criteria\n                        Syntax of this filter is described in the filter query parameter section:\n                        https://cloud.google.com/compute/docs/reference/latest/instances/list\n                      minLength: 1\n                      type: string\n                    port:\n                      description: |-\n                        The port to scrape metrics from. If using the public IP address, this must\n                        instead be specified in the relabeling rule.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    project:\n                      description: The Google Cloud Project ID\n                      minLength: 1\n                      type: string\n                    refreshInterval:\n                      description: RefreshInterval configures the refresh interval at which Prometheus will re-read the instance list.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    tagSeparator:\n                      description: The tag separator is used to separate the tags on concatenation\n                      minLength: 1\n                      type: string\n                    zone:\n                      description: The zone of the scrape targets. If you need multiple zones use multiple GCESDConfigs.\n                      minLength: 1\n                      type: string\n                  required:\n                  - project\n                  - zone\n                  type: object\n                type: array\n              hetznerSDConfigs:\n                description: HetznerSDConfigs defines a list of Hetzner service discovery configurations.\n                items:\n                  description: |-\n                    HetznerSDConfig allow retrieving scrape targets from Hetzner Cloud API and Robot API.\n                    This service discovery uses the public IPv4 address by default, but that can be changed with relabeling\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#hetzner_sd_config\n                  properties:\n                    authorization:\n                      description: |-\n                        Authorization header configuration, required when role is hcloud.\n                        Role robot does not support bearer token authentication.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: |-\n                        BasicAuth information to use on every scrape request, required when role is robot.\n                        Role hcloud does not support basic auth.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: Configure whether HTTP requests follow HTTP 3xx redirects.\n                      type: boolean\n                    labelSelector:\n                      description: |-\n                        Label selector used to filter the servers when fetching them from the API.\n                        It requires Prometheus >= v3.5.0.\n                      minLength: 1\n                      type: string\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth 2.0 configuration.\n                        Cannot be used at the same time as `basic_auth` or `authorization`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    port:\n                      description: The port to scrape metrics from.\n                      type: integer\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: The time after which the servers are refreshed.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    role:\n                      description: The Hetzner role of entities that should be discovered.\n                      enum:\n                      - hcloud\n                      - Hcloud\n                      - robot\n                      - Robot\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration to use on every scrape request.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  required:\n                  - role\n                  type: object\n                type: array\n              honorLabels:\n                description: HonorLabels chooses the metric's labels on collisions with target labels.\n                type: boolean\n              honorTimestamps:\n                description: HonorTimestamps controls whether Prometheus respects the timestamps present in scraped data.\n                type: boolean\n              httpSDConfigs:\n                description: HTTPSDConfigs defines a list of HTTP service discovery configurations.\n                items:\n                  description: |-\n                    HTTPSDConfig defines a prometheus HTTP service discovery configuration\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config\n                  properties:\n                    authorization:\n                      description: |-\n                        Authorization header configuration to authenticate against the target HTTP endpoint.\n                        Cannot be set at the same time as `oAuth2`, or `basicAuth`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: |-\n                        BasicAuth information to authenticate against the target HTTP endpoint.\n                        More info: https://prometheus.io/docs/operating/configuration/#endpoints\n                        Cannot be set at the same time as `authorization`, or `oAuth2`.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: Configure whether HTTP requests follow HTTP 3xx redirects.\n                      type: boolean\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth 2.0 configuration to authenticate against the target HTTP endpoint.\n                        Cannot be set at the same time as `authorization`, or `basicAuth`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: |-\n                        RefreshInterval configures the refresh interval at which Prometheus will re-query the\n                        endpoint to update the target list.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration applying to the target HTTP endpoint.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                    url:\n                      description: URL from which the targets are fetched.\n                      minLength: 1\n                      pattern: ^http(s)?://.+$\n                      type: string\n                  required:\n                  - url\n                  type: object\n                type: array\n              ionosSDConfigs:\n                description: IonosSDConfigs defines a list of IONOS service discovery configurations.\n                items:\n                  description: |-\n                    IonosSDConfig configurations allow retrieving scrape targets from IONOS resources.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#ionos_sd_config\n                  properties:\n                    authorization:\n                      description: Authorization` header configuration, required when using IONOS.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    datacenterID:\n                      description: The unique ID of the IONOS data center.\n                      minLength: 1\n                      type: string\n                    enableHTTP2:\n                      description: Configure whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: Configure whether the HTTP requests should follow HTTP 3xx redirects.\n                      type: boolean\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: Configure whether to enable OAuth2.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    port:\n                      description: Port to scrape the metrics from.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: Refresh interval to re-read the list of resources.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration to use when connecting to the IONOS API.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  required:\n                  - authorization\n                  - datacenterID\n                  type: object\n                type: array\n              jobName:\n                description: |-\n                  The value of the `job` label assigned to the scraped metrics by default.\n\n                  The `job_name` field in the rendered scrape configuration is always controlled by the\n                  operator to prevent duplicate job names, which Prometheus does not allow. Instead the\n                  `job` label is set by means of relabeling configs.\n                minLength: 1\n                type: string\n              keepDroppedTargets:\n                description: |-\n                  Per-scrape limit on the number of targets dropped by relabeling\n                  that will be kept in memory. 0 means no limit.\n\n                  It requires Prometheus >= v2.47.0.\n                format: int64\n                type: integer\n              kubernetesSDConfigs:\n                description: KubernetesSDConfigs defines a list of Kubernetes service discovery configurations.\n                items:\n                  description: |-\n                    KubernetesSDConfig allows retrieving scrape targets from Kubernetes' REST API.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config\n                  properties:\n                    apiServer:\n                      description: |-\n                        The API server address consisting of a hostname or IP address followed\n                        by an optional port number.\n                        If left empty, Prometheus is assumed to run inside\n                        of the cluster. It will discover API servers automatically and use the pod's\n                        CA certificate and bearer token file at /var/run/secrets/kubernetes.io/serviceaccount/.\n                      minLength: 1\n                      type: string\n                    attachMetadata:\n                      description: |-\n                        Optional metadata to attach to discovered targets.\n                        It requires Prometheus >= v2.35.0 when using the `Pod` role and\n                        Prometheus >= v2.37.0 for `Endpoints` and `Endpointslice` roles.\n                      properties:\n                        node:\n                          description: |-\n                            Attaches node metadata to discovered targets.\n                            When set to true, Prometheus must have the `get` permission on the\n                            `Nodes` objects.\n                            Only valid for Pod, Endpoint and Endpointslice roles.\n                          type: boolean\n                      type: object\n                    authorization:\n                      description: |-\n                        Authorization header to use on every scrape request.\n                        Cannot be set at the same time as `basicAuth`, or `oauth2`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: |-\n                        BasicAuth information to use on every scrape request.\n                        Cannot be set at the same time as `authorization`, or `oauth2`.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: Configure whether HTTP requests follow HTTP 3xx redirects.\n                      type: boolean\n                    namespaces:\n                      description: Optional namespace discovery. If omitted, Prometheus discovers targets across all namespaces.\n                      properties:\n                        names:\n                          description: |-\n                            List of namespaces where to watch for resources.\n                            If empty and `ownNamespace` isn't true, Prometheus watches for resources in all namespaces.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: set\n                        ownNamespace:\n                          description: Includes the namespace in which the Prometheus pod runs to the list of watched namespaces.\n                          type: boolean\n                      type: object\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth 2.0 configuration.\n                        Cannot be set at the same time as `authorization`, or `basicAuth`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    role:\n                      description: |-\n                        Role of the Kubernetes entities that should be discovered.\n                        Role `Endpointslice` requires Prometheus >= v2.21.0\n                      enum:\n                      - Pod\n                      - Endpoints\n                      - Ingress\n                      - Service\n                      - Node\n                      - EndpointSlice\n                      type: string\n                    selectors:\n                      description: |-\n                        Selector to select objects.\n                        It requires Prometheus >= v2.17.0\n                      items:\n                        description: K8SSelectorConfig is Kubernetes Selector Config\n                        properties:\n                          field:\n                            description: |-\n                              An optional field selector to limit the service discovery to resources which have fields with specific values.\n                              e.g: `metadata.name=foobar`\n                            minLength: 1\n                            type: string\n                          label:\n                            description: |-\n                              An optional label selector to limit the service discovery to resources with specific labels and label values.\n                              e.g: `node.kubernetes.io/instance-type=master`\n                            minLength: 1\n                            type: string\n                          role:\n                            description: |-\n                              Role specifies the type of Kubernetes resource to limit the service discovery to.\n                              Accepted values are: Node, Pod, Endpoints, EndpointSlice, Service, Ingress.\n                            enum:\n                            - Pod\n                            - Endpoints\n                            - Ingress\n                            - Service\n                            - Node\n                            - EndpointSlice\n                            type: string\n                        required:\n                        - role\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - role\n                      x-kubernetes-list-type: map\n                    tlsConfig:\n                      description: TLS configuration to connect to the Kubernetes API.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  required:\n                  - role\n                  type: object\n                type: array\n              kumaSDConfigs:\n                description: KumaSDConfigs defines a list of Kuma service discovery configurations.\n                items:\n                  description: |-\n                    KumaSDConfig allow retrieving scrape targets from Kuma's control plane.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kuma_sd_config\n                  properties:\n                    authorization:\n                      description: Authorization header to use on every scrape request.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: BasicAuth information to use on every scrape request.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    clientID:\n                      description: Client id is used by Kuma Control Plane to compute Monitoring Assignment for specific Prometheus backend.\n                      type: string\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    fetchTimeout:\n                      description: The time after which the monitoring assignments are refreshed.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    followRedirects:\n                      description: Configure whether HTTP requests follow HTTP 3xx redirects.\n                      type: boolean\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth 2.0 configuration.\n                        Cannot be set at the same time as `authorization`, or `basicAuth`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: The time to wait between polling update requests.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    server:\n                      description: Address of the Kuma Control Plane's MADS xDS server.\n                      minLength: 1\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration to use on every scrape request\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  required:\n                  - server\n                  type: object\n                type: array\n              labelLimit:\n                description: |-\n                  Per-scrape limit on number of labels that will be accepted for a sample.\n                  Only valid in Prometheus versions 2.27.0 and newer.\n                format: int64\n                type: integer\n              labelNameLengthLimit:\n                description: |-\n                  Per-scrape limit on length of labels name that will be accepted for a sample.\n                  Only valid in Prometheus versions 2.27.0 and newer.\n                format: int64\n                type: integer\n              labelValueLengthLimit:\n                description: |-\n                  Per-scrape limit on length of labels value that will be accepted for a sample.\n                  Only valid in Prometheus versions 2.27.0 and newer.\n                format: int64\n                type: integer\n              lightSailSDConfigs:\n                description: LightsailSDConfigs defines a list of Lightsail service discovery configurations.\n                items:\n                  description: |-\n                    LightSailSDConfig configurations allow retrieving scrape targets from AWS Lightsail instances.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#lightsail_sd_config\n                  properties:\n                    accessKey:\n                      description: AccessKey is the AWS API key.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    authorization:\n                      description: |-\n                        Optional `authorization` HTTP header configuration.\n                        Cannot be set at the same time as `basicAuth`, or `oauth2`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: |-\n                        Optional HTTP basic authentication information.\n                        Cannot be set at the same time as `authorization`, or `oauth2`.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    enableHTTP2:\n                      description: Configure whether to enable HTTP2.\n                      type: boolean\n                    endpoint:\n                      description: Custom endpoint to be used.\n                      minLength: 1\n                      type: string\n                    followRedirects:\n                      description: Configure whether the HTTP requests should follow HTTP 3xx redirects.\n                      type: boolean\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth2.0 configuration.\n                        Cannot be set at the same time as `basicAuth`, or `authorization`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    port:\n                      description: |-\n                        Port to scrape the metrics from.\n                        If using the public IP address, this must instead be specified in the relabeling rule.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: Refresh interval to re-read the list of instances.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    region:\n                      description: The AWS region.\n                      minLength: 1\n                      type: string\n                    roleARN:\n                      description: AWS Role ARN, an alternative to using AWS API keys.\n                      type: string\n                    secretKey:\n                      description: SecretKey is the AWS API secret.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    tlsConfig:\n                      description: TLS configuration to connect to the Puppet DB.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  type: object\n                type: array\n              linodeSDConfigs:\n                description: LinodeSDConfigs defines a list of Linode service discovery configurations.\n                items:\n                  description: |-\n                    LinodeSDConfig configurations allow retrieving scrape targets from Linode's Linode APIv4.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#linode_sd_config\n                  properties:\n                    authorization:\n                      description: Authorization header configuration.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: Configure whether HTTP requests follow HTTP 3xx redirects.\n                      type: boolean\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth 2.0 configuration.\n                        Cannot be used at the same time as `authorization`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    port:\n                      description: Default port to scrape metrics from.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: Time after which the linode instances are refreshed.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    region:\n                      description: Optional region to filter on.\n                      minLength: 1\n                      type: string\n                    tagSeparator:\n                      description: The string by which Linode Instance tags are joined into the tag label.\n                      minLength: 1\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration applying to the target HTTP endpoint.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  type: object\n                type: array\n              metricRelabelings:\n                description: MetricRelabelConfigs to apply to samples before ingestion.\n                items:\n                  description: |-\n                    RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                    scraped samples and remote write samples.\n\n                    More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                  properties:\n                    action:\n                      default: replace\n                      description: |-\n                        Action to perform based on the regex matching.\n\n                        `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                        `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                        Default: \"Replace\"\n                      enum:\n                      - replace\n                      - Replace\n                      - keep\n                      - Keep\n                      - drop\n                      - Drop\n                      - hashmod\n                      - HashMod\n                      - labelmap\n                      - LabelMap\n                      - labeldrop\n                      - LabelDrop\n                      - labelkeep\n                      - LabelKeep\n                      - lowercase\n                      - Lowercase\n                      - uppercase\n                      - Uppercase\n                      - keepequal\n                      - KeepEqual\n                      - dropequal\n                      - DropEqual\n                      type: string\n                    modulus:\n                      description: |-\n                        Modulus to take of the hash of the source label values.\n\n                        Only applicable when the action is `HashMod`.\n                      format: int64\n                      type: integer\n                    regex:\n                      description: Regular expression against which the extracted value is matched.\n                      type: string\n                    replacement:\n                      description: |-\n                        Replacement value against which a Replace action is performed if the\n                        regular expression matches.\n\n                        Regex capture groups are available.\n                      type: string\n                    separator:\n                      description: Separator is the string between concatenated SourceLabels.\n                      type: string\n                    sourceLabels:\n                      description: |-\n                        The source labels select values from existing labels. Their content is\n                        concatenated using the configured Separator and matched against the\n                        configured regular expression.\n                      items:\n                        description: |-\n                          LabelName is a valid Prometheus label name which may only contain ASCII\n                          letters, numbers, as well as underscores.\n                        pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                        type: string\n                      type: array\n                    targetLabel:\n                      description: |-\n                        Label to which the resulting string is written in a replacement.\n\n                        It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                        `KeepEqual` and `DropEqual` actions.\n\n                        Regex capture groups are available.\n                      type: string\n                  type: object\n                minItems: 1\n                type: array\n              metricsPath:\n                description: MetricsPath HTTP path to scrape for metrics. If empty, Prometheus uses the default value (e.g. /metrics).\n                minLength: 1\n                type: string\n              nameEscapingScheme:\n                description: |-\n                  Metric name escaping mode to request through content negotiation.\n\n                  It requires Prometheus >= v3.4.0.\n                enum:\n                - AllowUTF8\n                - Underscores\n                - Dots\n                - Values\n                type: string\n              nameValidationScheme:\n                description: |-\n                  Specifies the validation scheme for metric and label names.\n\n                  It requires Prometheus >= v3.0.0.\n                enum:\n                - UTF8\n                - Legacy\n                type: string\n              nativeHistogramBucketLimit:\n                description: |-\n                  If there are more than this many buckets in a native histogram,\n                  buckets will be merged to stay within the limit.\n                  It requires Prometheus >= v2.45.0.\n                format: int64\n                type: integer\n              nativeHistogramMinBucketFactor:\n                anyOf:\n                - type: integer\n                - type: string\n                description: |-\n                  If the growth factor of one bucket to the next is smaller than this,\n                  buckets will be merged to increase the factor sufficiently.\n                  It requires Prometheus >= v2.50.0.\n                pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                x-kubernetes-int-or-string: true\n              noProxy:\n                description: |-\n                  `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                  that should be excluded from proxying. IP and domain names can\n                  contain port numbers.\n\n                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                type: string\n              nomadSDConfigs:\n                description: NomadSDConfigs defines a list of Nomad service discovery configurations.\n                items:\n                  description: |-\n                    NomadSDConfig configurations allow retrieving scrape targets from Nomad's Service API.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#nomad_sd_config\n                  properties:\n                    allowStale:\n                      description: |-\n                        The information to access the Nomad API. It is to be defined\n                        as the Nomad documentation requires.\n                      type: boolean\n                    authorization:\n                      description: Authorization header to use on every scrape request.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: BasicAuth information to use on every scrape request.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: Configure whether HTTP requests follow HTTP 3xx redirects.\n                      type: boolean\n                    namespace:\n                      type: string\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth 2.0 configuration.\n                        Cannot be set at the same time as `authorization` or `basic_auth`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: |-\n                        Duration is a valid time duration that can be parsed by Prometheus model.ParseDuration() function.\n                        Supported units: y, w, d, h, m, s, ms\n                        Examples: `30s`, `1m`, `1h20m15s`, `15d`\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    region:\n                      type: string\n                    server:\n                      minLength: 1\n                      type: string\n                    tagSeparator:\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration applying to the target HTTP endpoint.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                  required:\n                  - server\n                  type: object\n                type: array\n              oauth2:\n                description: OAuth2 configuration to use on every scrape request.\n                properties:\n                  clientId:\n                    description: |-\n                      `clientId` specifies a key of a Secret or ConfigMap containing the\n                      OAuth2 client's ID.\n                    properties:\n                      configMap:\n                        description: ConfigMap containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key to select.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the ConfigMap or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      secret:\n                        description: Secret containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  clientSecret:\n                    description: |-\n                      `clientSecret` specifies a key of a Secret containing the OAuth2\n                      client's secret.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  endpointParams:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      `endpointParams` configures the HTTP parameters to append to the token\n                      URL.\n                    type: object\n                  noProxy:\n                    description: |-\n                      `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                      that should be excluded from proxying. IP and domain names can\n                      contain port numbers.\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: string\n                  proxyConnectHeader:\n                    additionalProperties:\n                      items:\n                        description: SecretKeySelector selects a key of a Secret.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      type: array\n                    description: |-\n                      ProxyConnectHeader optionally specifies headers to send to\n                      proxies during CONNECT requests.\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  proxyFromEnvironment:\n                    description: |-\n                      Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                      It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                    type: boolean\n                  proxyUrl:\n                    description: '`proxyURL` defines the HTTP proxy server to use.'\n                    pattern: ^(http|https|socks5)://.+$\n                    type: string\n                  scopes:\n                    description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                    items:\n                      type: string\n                    type: array\n                  tlsConfig:\n                    description: |-\n                      TLS configuration to use when connecting to the OAuth2 server.\n                      It requires Prometheus >= v2.43.0.\n                    properties:\n                      ca:\n                        description: Certificate authority used when verifying server certificates.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      cert:\n                        description: Client certificate to present when doing client-authentication.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      insecureSkipVerify:\n                        description: Disable target certificate validation.\n                        type: boolean\n                      keySecret:\n                        description: Secret containing the client key file for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: |-\n                          Maximum acceptable TLS version.\n\n                          It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      minVersion:\n                        description: |-\n                          Minimum acceptable TLS version.\n\n                          It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                        enum:\n                        - TLS10\n                        - TLS11\n                        - TLS12\n                        - TLS13\n                        type: string\n                      serverName:\n                        description: Used to verify the hostname for the targets.\n                        type: string\n                    type: object\n                  tokenUrl:\n                    description: '`tokenURL` configures the URL to fetch the token from.'\n                    minLength: 1\n                    type: string\n                required:\n                - clientId\n                - clientSecret\n                - tokenUrl\n                type: object\n              openstackSDConfigs:\n                description: OpenStackSDConfigs defines a list of OpenStack service discovery configurations.\n                items:\n                  description: |-\n                    OpenStackSDConfig allow retrieving scrape targets from OpenStack Nova instances.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#openstack_sd_config\n                  properties:\n                    allTenants:\n                      description: |-\n                        Whether the service discovery should list all instances for all projects.\n                        It is only relevant for the 'instance' role and usually requires admin permissions.\n                      type: boolean\n                    applicationCredentialId:\n                      description: ApplicationCredentialID\n                      type: string\n                    applicationCredentialName:\n                      description: |-\n                        The ApplicationCredentialID or ApplicationCredentialName fields are\n                        required if using an application credential to authenticate. Some providers\n                        allow you to create an application credential to authenticate rather than a\n                        password.\n                      minLength: 1\n                      type: string\n                    applicationCredentialSecret:\n                      description: |-\n                        The applicationCredentialSecret field is required if using an application\n                        credential to authenticate.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    availability:\n                      description: Availability of the endpoint to connect to.\n                      enum:\n                      - Public\n                      - public\n                      - Admin\n                      - admin\n                      - Internal\n                      - internal\n                      type: string\n                    domainID:\n                      description: DomainID\n                      minLength: 1\n                      type: string\n                    domainName:\n                      description: |-\n                        At most one of domainId and domainName must be provided if using username\n                        with Identity V3. Otherwise, either are optional.\n                      minLength: 1\n                      type: string\n                    identityEndpoint:\n                      description: |-\n                        IdentityEndpoint specifies the HTTP endpoint that is required to work with\n                        the Identity API of the appropriate version.\n                      pattern: ^http(s)?:\\/\\/.+$\n                      type: string\n                    password:\n                      description: |-\n                        Password for the Identity V2 and V3 APIs. Consult with your provider's\n                        control panel to discover your account's preferred method of authentication.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    port:\n                      description: |-\n                        The port to scrape metrics from. If using the public IP address, this must\n                        instead be specified in the relabeling rule.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    projectID:\n                      description: ' ProjectID'\n                      minLength: 1\n                      type: string\n                    projectName:\n                      description: |-\n                        The ProjectId and ProjectName fields are optional for the Identity V2 API.\n                        Some providers allow you to specify a ProjectName instead of the ProjectId.\n                        Some require both. Your provider's authentication policies will determine\n                        how these fields influence authentication.\n                      minLength: 1\n                      type: string\n                    refreshInterval:\n                      description: Refresh interval to re-read the instance list.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    region:\n                      description: The OpenStack Region.\n                      minLength: 1\n                      type: string\n                    role:\n                      description: |-\n                        The OpenStack role of entities that should be discovered.\n\n                        Note: The `LoadBalancer` role requires Prometheus >= v3.2.0.\n                      enum:\n                      - Instance\n                      - Hypervisor\n                      - LoadBalancer\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration applying to the target HTTP endpoint.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                    userid:\n                      description: UserID\n                      minLength: 1\n                      type: string\n                    username:\n                      description: |-\n                        Username is required if using Identity V2 API. Consult with your provider's\n                        control panel to discover your account's username.\n                        In Identity V3, either userid or a combination of username\n                        and domainId or domainName are needed\n                      minLength: 1\n                      type: string\n                  required:\n                  - region\n                  - role\n                  type: object\n                type: array\n              ovhcloudSDConfigs:\n                description: OVHCloudSDConfigs defines a list of OVHcloud service discovery configurations.\n                items:\n                  description: |-\n                    OVHCloudSDConfig configurations allow retrieving scrape targets from OVHcloud's dedicated servers and VPS using their API.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#ovhcloud_sd_config\n                  properties:\n                    applicationKey:\n                      description: Access key to use. https://api.ovh.com.\n                      minLength: 1\n                      type: string\n                    applicationSecret:\n                      description: SecretKeySelector selects a key of a Secret.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    consumerKey:\n                      description: SecretKeySelector selects a key of a Secret.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    endpoint:\n                      description: Custom endpoint to be used.\n                      minLength: 1\n                      type: string\n                    refreshInterval:\n                      description: Refresh interval to re-read the resources list.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    service:\n                      allOf:\n                      - enum:\n                        - VPS\n                        - DedicatedServer\n                      - enum:\n                        - VPS\n                        - DedicatedServer\n                      description: Service of the targets to retrieve. Must be `VPS` or `DedicatedServer`.\n                      type: string\n                  required:\n                  - applicationKey\n                  - applicationSecret\n                  - consumerKey\n                  - service\n                  type: object\n                type: array\n              params:\n                additionalProperties:\n                  items:\n                    type: string\n                  type: array\n                description: Optional HTTP URL parameters\n                type: object\n                x-kubernetes-map-type: atomic\n              proxyConnectHeader:\n                additionalProperties:\n                  items:\n                    description: SecretKeySelector selects a key of a Secret.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  type: array\n                description: |-\n                  ProxyConnectHeader optionally specifies headers to send to\n                  proxies during CONNECT requests.\n\n                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                type: object\n                x-kubernetes-map-type: atomic\n              proxyFromEnvironment:\n                description: |-\n                  Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                  It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                type: boolean\n              proxyUrl:\n                description: '`proxyURL` defines the HTTP proxy server to use.'\n                pattern: ^(http|https|socks5)://.+$\n                type: string\n              puppetDBSDConfigs:\n                description: PuppetDBSDConfigs defines a list of PuppetDB service discovery configurations.\n                items:\n                  description: |-\n                    PuppetDBSDConfig configurations allow retrieving scrape targets from PuppetDB resources.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#puppetdb_sd_config\n                  properties:\n                    authorization:\n                      description: |-\n                        Optional `authorization` HTTP header configuration.\n                        Cannot be set at the same time as `basicAuth`, or `oauth2`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: |-\n                        Optional HTTP basic authentication information.\n                        Cannot be set at the same time as `authorization`, or `oauth2`.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    enableHTTP2:\n                      description: Configure whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: Configure whether the HTTP requests should follow HTTP 3xx redirects.\n                      type: boolean\n                    includeParameters:\n                      description: |-\n                        Whether to include the parameters as meta labels.\n                        Note: Enabling this exposes parameters in the Prometheus UI and API. Make sure\n                        that you don't have secrets exposed as parameters if you enable this.\n                      type: boolean\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        Optional OAuth2.0 configuration.\n                        Cannot be set at the same time as `basicAuth`, or `authorization`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    port:\n                      description: Port to scrape the metrics from.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    query:\n                      description: |-\n                        Puppet Query Language (PQL) query. Only resources are supported.\n                        https://puppet.com/docs/puppetdb/latest/api/query/v4/pql.html\n                      minLength: 1\n                      type: string\n                    refreshInterval:\n                      description: Refresh interval to re-read the list of resources.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    tlsConfig:\n                      description: TLS configuration to connect to the Puppet DB.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                    url:\n                      description: The URL of the PuppetDB root query endpoint.\n                      minLength: 1\n                      pattern: ^http(s)?://.+$\n                      type: string\n                  required:\n                  - query\n                  - url\n                  type: object\n                type: array\n              relabelings:\n                description: |-\n                  RelabelConfigs defines how to rewrite the target's labels before scraping.\n                  Prometheus Operator automatically adds relabelings for a few standard Kubernetes fields.\n                  The original scrape job's name is available via the `__tmp_prometheus_job_name` label.\n                  More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                items:\n                  description: |-\n                    RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                    scraped samples and remote write samples.\n\n                    More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                  properties:\n                    action:\n                      default: replace\n                      description: |-\n                        Action to perform based on the regex matching.\n\n                        `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                        `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                        Default: \"Replace\"\n                      enum:\n                      - replace\n                      - Replace\n                      - keep\n                      - Keep\n                      - drop\n                      - Drop\n                      - hashmod\n                      - HashMod\n                      - labelmap\n                      - LabelMap\n                      - labeldrop\n                      - LabelDrop\n                      - labelkeep\n                      - LabelKeep\n                      - lowercase\n                      - Lowercase\n                      - uppercase\n                      - Uppercase\n                      - keepequal\n                      - KeepEqual\n                      - dropequal\n                      - DropEqual\n                      type: string\n                    modulus:\n                      description: |-\n                        Modulus to take of the hash of the source label values.\n\n                        Only applicable when the action is `HashMod`.\n                      format: int64\n                      type: integer\n                    regex:\n                      description: Regular expression against which the extracted value is matched.\n                      type: string\n                    replacement:\n                      description: |-\n                        Replacement value against which a Replace action is performed if the\n                        regular expression matches.\n\n                        Regex capture groups are available.\n                      type: string\n                    separator:\n                      description: Separator is the string between concatenated SourceLabels.\n                      type: string\n                    sourceLabels:\n                      description: |-\n                        The source labels select values from existing labels. Their content is\n                        concatenated using the configured Separator and matched against the\n                        configured regular expression.\n                      items:\n                        description: |-\n                          LabelName is a valid Prometheus label name which may only contain ASCII\n                          letters, numbers, as well as underscores.\n                        pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                        type: string\n                      type: array\n                    targetLabel:\n                      description: |-\n                        Label to which the resulting string is written in a replacement.\n\n                        It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                        `KeepEqual` and `DropEqual` actions.\n\n                        Regex capture groups are available.\n                      type: string\n                  type: object\n                minItems: 1\n                type: array\n              sampleLimit:\n                description: SampleLimit defines per-scrape limit on number of scraped samples that will be accepted.\n                format: int64\n                type: integer\n              scalewaySDConfigs:\n                description: ScalewaySDConfigs defines a list of Scaleway instances and baremetal service discovery configurations.\n                items:\n                  description: |-\n                    ScalewaySDConfig configurations allow retrieving scrape targets from Scaleway instances and baremetal services.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scaleway_sd_config\n                  properties:\n                    accessKey:\n                      description: Access key to use. https://console.scaleway.com/project/credentials\n                      minLength: 1\n                      type: string\n                    apiURL:\n                      description: API URL to use when doing the server listing requests.\n                      pattern: ^http(s)?://.+$\n                      type: string\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: Configure whether HTTP requests follow HTTP 3xx redirects.\n                      type: boolean\n                    nameFilter:\n                      description: NameFilter specify a name filter (works as a LIKE) to apply on the server listing request.\n                      minLength: 1\n                      type: string\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    port:\n                      description: The port to scrape metrics from.\n                      format: int32\n                      maximum: 65535\n                      minimum: 0\n                      type: integer\n                    projectID:\n                      description: Project ID of the targets.\n                      minLength: 1\n                      type: string\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    refreshInterval:\n                      description: Refresh interval to re-read the list of instances.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    role:\n                      description: Service of the targets to retrieve. Must be `Instance` or `Baremetal`.\n                      enum:\n                      - Instance\n                      - Baremetal\n                      type: string\n                    secretKey:\n                      description: Secret key to use when listing targets.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    tagsFilter:\n                      description: TagsFilter specify a tag filter (a server needs to have all defined tags to be listed) to apply on the server listing request.\n                      items:\n                        minLength: 1\n                        type: string\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-type: set\n                    tlsConfig:\n                      description: TLS configuration to use on every scrape request\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                    zone:\n                      description: Zone is the availability zone of your targets (e.g. fr-par-1).\n                      minLength: 1\n                      type: string\n                  required:\n                  - accessKey\n                  - projectID\n                  - role\n                  - secretKey\n                  type: object\n                type: array\n              scheme:\n                description: |-\n                  Configures the protocol scheme used for requests.\n                  If empty, Prometheus uses HTTP by default.\n                enum:\n                - HTTP\n                - HTTPS\n                type: string\n              scrapeClass:\n                description: The scrape class to apply.\n                minLength: 1\n                type: string\n              scrapeClassicHistograms:\n                description: |-\n                  Whether to scrape a classic histogram that is also exposed as a native histogram.\n                  It requires Prometheus >= v2.45.0.\n\n                  Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration.\n                type: boolean\n              scrapeInterval:\n                description: ScrapeInterval is the interval between consecutive scrapes.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              scrapeProtocols:\n                description: |-\n                  The protocols to negotiate during a scrape. It tells clients the\n                  protocols supported by Prometheus in order of preference (from most to least preferred).\n\n                  If unset, Prometheus uses its default value.\n\n                  It requires Prometheus >= v2.49.0.\n                items:\n                  description: |-\n                    ScrapeProtocol represents a protocol used by Prometheus for scraping metrics.\n                    Supported values are:\n                    * `OpenMetricsText0.0.1`\n                    * `OpenMetricsText1.0.0`\n                    * `PrometheusProto`\n                    * `PrometheusText0.0.4`\n                    * `PrometheusText1.0.0`\n                  enum:\n                  - PrometheusProto\n                  - OpenMetricsText0.0.1\n                  - OpenMetricsText1.0.0\n                  - PrometheusText0.0.4\n                  - PrometheusText1.0.0\n                  type: string\n                minItems: 1\n                type: array\n                x-kubernetes-list-type: set\n              scrapeTimeout:\n                description: |-\n                  ScrapeTimeout is the number of seconds to wait until a scrape request times out.\n                  The value cannot be greater than the scrape interval otherwise the operator will reject the resource.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              staticConfigs:\n                description: StaticConfigs defines a list of static targets with a common label set.\n                items:\n                  description: |-\n                    StaticConfig defines a Prometheus static configuration.\n                    See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config\n                  properties:\n                    labels:\n                      additionalProperties:\n                        type: string\n                      description: Labels assigned to all metrics scraped from the targets.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    targets:\n                      description: List of targets for this static configuration.\n                      items:\n                        description: |-\n                          Target represents a target for Prometheus to scrape\n                          kubebuilder:validation:MinLength:=1\n                        type: string\n                      minItems: 1\n                      type: array\n                      x-kubernetes-list-type: set\n                  required:\n                  - targets\n                  type: object\n                type: array\n              targetLimit:\n                description: TargetLimit defines a limit on the number of scraped targets that will be accepted.\n                format: int64\n                type: integer\n              tlsConfig:\n                description: TLS configuration to use on every scrape request\n                properties:\n                  ca:\n                    description: Certificate authority used when verifying server certificates.\n                    properties:\n                      configMap:\n                        description: ConfigMap containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key to select.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the ConfigMap or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      secret:\n                        description: Secret containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  cert:\n                    description: Client certificate to present when doing client-authentication.\n                    properties:\n                      configMap:\n                        description: ConfigMap containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key to select.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the ConfigMap or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      secret:\n                        description: Secret containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  insecureSkipVerify:\n                    description: Disable target certificate validation.\n                    type: boolean\n                  keySecret:\n                    description: Secret containing the client key file for the targets.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  maxVersion:\n                    description: |-\n                      Maximum acceptable TLS version.\n\n                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                    enum:\n                    - TLS10\n                    - TLS11\n                    - TLS12\n                    - TLS13\n                    type: string\n                  minVersion:\n                    description: |-\n                      Minimum acceptable TLS version.\n\n                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                    enum:\n                    - TLS10\n                    - TLS11\n                    - TLS12\n                    - TLS13\n                    type: string\n                  serverName:\n                    description: Used to verify the hostname for the targets.\n                    type: string\n                type: object\n              trackTimestampsStaleness:\n                description: |-\n                  TrackTimestampsStaleness whether Prometheus tracks staleness of\n                  the metrics that have an explicit timestamp present in scraped data.\n                  Has no effect if `honorTimestamps` is false.\n                  It requires Prometheus >= v2.48.0.\n                type: boolean\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n"
  },
  {
    "path": "hack/config/monitoring/crds/0servicemonitorCustomResourceDefinition.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.18.0\n    operator.prometheus.io/version: 0.85.0\n  name: servicemonitors.monitoring.coreos.com\nspec:\n  group: monitoring.coreos.com\n  names:\n    categories:\n    - prometheus-operator\n    kind: ServiceMonitor\n    listKind: ServiceMonitorList\n    plural: servicemonitors\n    shortNames:\n    - smon\n    singular: servicemonitor\n  scope: Namespaced\n  versions:\n  - name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The `ServiceMonitor` custom resource definition (CRD) defines how `Prometheus` and `PrometheusAgent` can scrape metrics from a group of services.\n          Among other things, it allows to specify:\n          * The services to scrape via label selectors.\n          * The container ports to scrape.\n          * Authentication credentials to use.\n          * Target and metric relabeling.\n\n          `Prometheus` and `PrometheusAgent` objects select `ServiceMonitor` objects using label and namespace selectors.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: |-\n              Specification of desired Service selection for target discovery by\n              Prometheus.\n            properties:\n              attachMetadata:\n                description: |-\n                  `attachMetadata` defines additional metadata which is added to the\n                  discovered targets.\n\n                  It requires Prometheus >= v2.37.0.\n                properties:\n                  node:\n                    description: |-\n                      When set to true, Prometheus attaches node metadata to the discovered\n                      targets.\n\n                      The Prometheus service account must have the `list` and `watch`\n                      permissions on the `Nodes` objects.\n                    type: boolean\n                type: object\n              bodySizeLimit:\n                description: |-\n                  When defined, bodySizeLimit specifies a job level limit on the size\n                  of uncompressed response body that will be accepted by Prometheus.\n\n                  It requires Prometheus >= v2.28.0.\n                pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$\n                type: string\n              convertClassicHistogramsToNHCB:\n                description: |-\n                  Whether to convert all scraped classic histograms into a native histogram with custom buckets.\n                  It requires Prometheus >= v3.0.0.\n                type: boolean\n              endpoints:\n                description: |-\n                  List of endpoints part of this ServiceMonitor.\n                  Defines how to scrape metrics from Kubernetes [Endpoints](https://kubernetes.io/docs/concepts/services-networking/service/#endpoints) objects.\n                  In most cases, an Endpoints object is backed by a Kubernetes [Service](https://kubernetes.io/docs/concepts/services-networking/service/) object with the same name and labels.\n                items:\n                  description: |-\n                    Endpoint defines an endpoint serving Prometheus metrics to be scraped by\n                    Prometheus.\n                  properties:\n                    authorization:\n                      description: |-\n                        `authorization` configures the Authorization header credentials to use when\n                        scraping the target.\n\n                        Cannot be set at the same time as `basicAuth`, or `oauth2`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    basicAuth:\n                      description: |-\n                        `basicAuth` configures the Basic Authentication credentials to use when\n                        scraping the target.\n\n                        Cannot be set at the same time as `authorization`, or `oauth2`.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    bearerTokenFile:\n                      description: |-\n                        File to read bearer token for scraping the target.\n\n                        Deprecated: use `authorization` instead.\n                      type: string\n                    bearerTokenSecret:\n                      description: |-\n                        `bearerTokenSecret` specifies a key of a Secret containing the bearer\n                        token for scraping targets. The secret needs to be in the same namespace\n                        as the ServiceMonitor object and readable by the Prometheus Operator.\n\n                        Deprecated: use `authorization` instead.\n                      properties:\n                        key:\n                          description: The key of the secret to select from.  Must be a valid secret key.\n                          type: string\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: Specify whether the Secret or its key must be defined\n                          type: boolean\n                      required:\n                      - key\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    enableHttp2:\n                      description: '`enableHttp2` can be used to disable HTTP2 when scraping the target.'\n                      type: boolean\n                    filterRunning:\n                      description: |-\n                        When true, the pods which are not running (e.g. either in Failed or\n                        Succeeded state) are dropped during the target discovery.\n\n                        If unset, the filtering is enabled.\n\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase\n                      type: boolean\n                    followRedirects:\n                      description: |-\n                        `followRedirects` defines whether the scrape requests should follow HTTP\n                        3xx redirects.\n                      type: boolean\n                    honorLabels:\n                      description: |-\n                        When true, `honorLabels` preserves the metric's labels when they collide\n                        with the target's labels.\n                      type: boolean\n                    honorTimestamps:\n                      description: |-\n                        `honorTimestamps` controls whether Prometheus preserves the timestamps\n                        when exposed by the target.\n                      type: boolean\n                    interval:\n                      description: |-\n                        Interval at which Prometheus scrapes the metrics from the target.\n\n                        If empty, Prometheus uses the global scrape interval.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    metricRelabelings:\n                      description: |-\n                        `metricRelabelings` configures the relabeling rules to apply to the\n                        samples before ingestion.\n                      items:\n                        description: |-\n                          RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                          scraped samples and remote write samples.\n\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        properties:\n                          action:\n                            default: replace\n                            description: |-\n                              Action to perform based on the regex matching.\n\n                              `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                              `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                              Default: \"Replace\"\n                            enum:\n                            - replace\n                            - Replace\n                            - keep\n                            - Keep\n                            - drop\n                            - Drop\n                            - hashmod\n                            - HashMod\n                            - labelmap\n                            - LabelMap\n                            - labeldrop\n                            - LabelDrop\n                            - labelkeep\n                            - LabelKeep\n                            - lowercase\n                            - Lowercase\n                            - uppercase\n                            - Uppercase\n                            - keepequal\n                            - KeepEqual\n                            - dropequal\n                            - DropEqual\n                            type: string\n                          modulus:\n                            description: |-\n                              Modulus to take of the hash of the source label values.\n\n                              Only applicable when the action is `HashMod`.\n                            format: int64\n                            type: integer\n                          regex:\n                            description: Regular expression against which the extracted value is matched.\n                            type: string\n                          replacement:\n                            description: |-\n                              Replacement value against which a Replace action is performed if the\n                              regular expression matches.\n\n                              Regex capture groups are available.\n                            type: string\n                          separator:\n                            description: Separator is the string between concatenated SourceLabels.\n                            type: string\n                          sourceLabels:\n                            description: |-\n                              The source labels select values from existing labels. Their content is\n                              concatenated using the configured Separator and matched against the\n                              configured regular expression.\n                            items:\n                              description: |-\n                                LabelName is a valid Prometheus label name which may only contain ASCII\n                                letters, numbers, as well as underscores.\n                              pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                              type: string\n                            type: array\n                          targetLabel:\n                            description: |-\n                              Label to which the resulting string is written in a replacement.\n\n                              It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                              `KeepEqual` and `DropEqual` actions.\n\n                              Regex capture groups are available.\n                            type: string\n                        type: object\n                      type: array\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        `oauth2` configures the OAuth2 settings to use when scraping the target.\n\n                        It requires Prometheus >= 2.27.0.\n\n                        Cannot be set at the same time as `authorization`, or `basicAuth`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    params:\n                      additionalProperties:\n                        items:\n                          type: string\n                        type: array\n                      description: params define optional HTTP URL parameters.\n                      type: object\n                    path:\n                      description: |-\n                        HTTP path from which to scrape for metrics.\n\n                        If empty, Prometheus uses the default value (e.g. `/metrics`).\n                      type: string\n                    port:\n                      description: |-\n                        Name of the Service port which this endpoint refers to.\n\n                        It takes precedence over `targetPort`.\n                      type: string\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    relabelings:\n                      description: |-\n                        `relabelings` configures the relabeling rules to apply the target's\n                        metadata labels.\n\n                        The Operator automatically adds relabelings for a few standard Kubernetes fields.\n\n                        The original scrape job's name is available via the `__tmp_prometheus_job_name` label.\n\n                        More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                      items:\n                        description: |-\n                          RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                          scraped samples and remote write samples.\n\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        properties:\n                          action:\n                            default: replace\n                            description: |-\n                              Action to perform based on the regex matching.\n\n                              `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                              `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                              Default: \"Replace\"\n                            enum:\n                            - replace\n                            - Replace\n                            - keep\n                            - Keep\n                            - drop\n                            - Drop\n                            - hashmod\n                            - HashMod\n                            - labelmap\n                            - LabelMap\n                            - labeldrop\n                            - LabelDrop\n                            - labelkeep\n                            - LabelKeep\n                            - lowercase\n                            - Lowercase\n                            - uppercase\n                            - Uppercase\n                            - keepequal\n                            - KeepEqual\n                            - dropequal\n                            - DropEqual\n                            type: string\n                          modulus:\n                            description: |-\n                              Modulus to take of the hash of the source label values.\n\n                              Only applicable when the action is `HashMod`.\n                            format: int64\n                            type: integer\n                          regex:\n                            description: Regular expression against which the extracted value is matched.\n                            type: string\n                          replacement:\n                            description: |-\n                              Replacement value against which a Replace action is performed if the\n                              regular expression matches.\n\n                              Regex capture groups are available.\n                            type: string\n                          separator:\n                            description: Separator is the string between concatenated SourceLabels.\n                            type: string\n                          sourceLabels:\n                            description: |-\n                              The source labels select values from existing labels. Their content is\n                              concatenated using the configured Separator and matched against the\n                              configured regular expression.\n                            items:\n                              description: |-\n                                LabelName is a valid Prometheus label name which may only contain ASCII\n                                letters, numbers, as well as underscores.\n                              pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                              type: string\n                            type: array\n                          targetLabel:\n                            description: |-\n                              Label to which the resulting string is written in a replacement.\n\n                              It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                              `KeepEqual` and `DropEqual` actions.\n\n                              Regex capture groups are available.\n                            type: string\n                        type: object\n                      type: array\n                    scheme:\n                      description: |-\n                        HTTP scheme to use for scraping.\n\n                        `http` and `https` are the expected values unless you rewrite the\n                        `__scheme__` label via relabeling.\n\n                        If empty, Prometheus uses the default value `http`.\n                      enum:\n                      - http\n                      - https\n                      type: string\n                    scrapeTimeout:\n                      description: |-\n                        Timeout after which Prometheus considers the scrape to be failed.\n\n                        If empty, Prometheus uses the global scrape timeout unless it is less\n                        than the target's scrape interval value in which the latter is used.\n                        The value cannot be greater than the scrape interval otherwise the operator will reject the resource.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    targetPort:\n                      anyOf:\n                      - type: integer\n                      - type: string\n                      description: |-\n                        Name or number of the target port of the `Pod` object behind the\n                        Service. The port must be specified with the container's port property.\n                      x-kubernetes-int-or-string: true\n                    tlsConfig:\n                      description: TLS configuration to use when scraping the target.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        caFile:\n                          description: Path to the CA cert in the Prometheus container to use for the targets.\n                          type: string\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        certFile:\n                          description: Path to the client cert file in the Prometheus container for the targets.\n                          type: string\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keyFile:\n                          description: Path to the client key file in the Prometheus container for the targets.\n                          type: string\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                    trackTimestampsStaleness:\n                      description: |-\n                        `trackTimestampsStaleness` defines whether Prometheus tracks staleness of\n                        the metrics that have an explicit timestamp present in scraped data.\n                        Has no effect if `honorTimestamps` is false.\n\n                        It requires Prometheus >= v2.48.0.\n                      type: boolean\n                  type: object\n                type: array\n              fallbackScrapeProtocol:\n                description: |-\n                  The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type.\n\n                  It requires Prometheus >= v3.0.0.\n                enum:\n                - PrometheusProto\n                - OpenMetricsText0.0.1\n                - OpenMetricsText1.0.0\n                - PrometheusText0.0.4\n                - PrometheusText1.0.0\n                type: string\n              jobLabel:\n                description: |-\n                  `jobLabel` selects the label from the associated Kubernetes `Service`\n                  object which will be used as the `job` label for all metrics.\n\n                  For example if `jobLabel` is set to `foo` and the Kubernetes `Service`\n                  object is labeled with `foo: bar`, then Prometheus adds the `job=\"bar\"`\n                  label to all ingested metrics.\n\n                  If the value of this field is empty or if the label doesn't exist for\n                  the given Service, the `job` label of the metrics defaults to the name\n                  of the associated Kubernetes `Service`.\n                type: string\n              keepDroppedTargets:\n                description: |-\n                  Per-scrape limit on the number of targets dropped by relabeling\n                  that will be kept in memory. 0 means no limit.\n\n                  It requires Prometheus >= v2.47.0.\n                format: int64\n                type: integer\n              labelLimit:\n                description: |-\n                  Per-scrape limit on number of labels that will be accepted for a sample.\n\n                  It requires Prometheus >= v2.27.0.\n                format: int64\n                type: integer\n              labelNameLengthLimit:\n                description: |-\n                  Per-scrape limit on length of labels name that will be accepted for a sample.\n\n                  It requires Prometheus >= v2.27.0.\n                format: int64\n                type: integer\n              labelValueLengthLimit:\n                description: |-\n                  Per-scrape limit on length of labels value that will be accepted for a sample.\n\n                  It requires Prometheus >= v2.27.0.\n                format: int64\n                type: integer\n              namespaceSelector:\n                description: |-\n                  `namespaceSelector` defines in which namespace(s) Prometheus should discover the services.\n                  By default, the services are discovered in the same namespace as the `ServiceMonitor` object but it is possible to select pods across different/all namespaces.\n                properties:\n                  any:\n                    description: |-\n                      Boolean describing whether all namespaces are selected in contrast to a\n                      list restricting them.\n                    type: boolean\n                  matchNames:\n                    description: List of namespace names to select from.\n                    items:\n                      type: string\n                    type: array\n                type: object\n              nativeHistogramBucketLimit:\n                description: |-\n                  If there are more than this many buckets in a native histogram,\n                  buckets will be merged to stay within the limit.\n                  It requires Prometheus >= v2.45.0.\n                format: int64\n                type: integer\n              nativeHistogramMinBucketFactor:\n                anyOf:\n                - type: integer\n                - type: string\n                description: |-\n                  If the growth factor of one bucket to the next is smaller than this,\n                  buckets will be merged to increase the factor sufficiently.\n                  It requires Prometheus >= v2.50.0.\n                pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                x-kubernetes-int-or-string: true\n              podTargetLabels:\n                description: |-\n                  `podTargetLabels` defines the labels which are transferred from the\n                  associated Kubernetes `Pod` object onto the ingested metrics.\n                items:\n                  type: string\n                type: array\n              sampleLimit:\n                description: |-\n                  `sampleLimit` defines a per-scrape limit on the number of scraped samples\n                  that will be accepted.\n                format: int64\n                type: integer\n              scrapeClass:\n                description: The scrape class to apply.\n                minLength: 1\n                type: string\n              scrapeClassicHistograms:\n                description: |-\n                  Whether to scrape a classic histogram that is also exposed as a native histogram.\n                  It requires Prometheus >= v2.45.0.\n\n                  Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration.\n                type: boolean\n              scrapeProtocols:\n                description: |-\n                  `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the\n                  protocols supported by Prometheus in order of preference (from most to least preferred).\n\n                  If unset, Prometheus uses its default value.\n\n                  It requires Prometheus >= v2.49.0.\n                items:\n                  description: |-\n                    ScrapeProtocol represents a protocol used by Prometheus for scraping metrics.\n                    Supported values are:\n                    * `OpenMetricsText0.0.1`\n                    * `OpenMetricsText1.0.0`\n                    * `PrometheusProto`\n                    * `PrometheusText0.0.4`\n                    * `PrometheusText1.0.0`\n                  enum:\n                  - PrometheusProto\n                  - OpenMetricsText0.0.1\n                  - OpenMetricsText1.0.0\n                  - PrometheusText0.0.4\n                  - PrometheusText1.0.0\n                  type: string\n                type: array\n                x-kubernetes-list-type: set\n              selector:\n                description: Label selector to select the Kubernetes `Endpoints` objects to scrape metrics from.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              selectorMechanism:\n                description: |-\n                  Mechanism used to select the endpoints to scrape.\n                  By default, the selection process relies on relabel configurations to filter the discovered targets.\n                  Alternatively, you can opt in for role selectors, which may offer better efficiency in large clusters.\n                  Which strategy is best for your use case needs to be carefully evaluated.\n\n                  It requires Prometheus >= v2.17.0.\n                enum:\n                - RelabelConfig\n                - RoleSelector\n                type: string\n              targetLabels:\n                description: |-\n                  `targetLabels` defines the labels which are transferred from the\n                  associated Kubernetes `Service` object onto the ingested metrics.\n                items:\n                  type: string\n                type: array\n              targetLimit:\n                description: |-\n                  `targetLimit` defines a limit on the number of scraped targets that will\n                  be accepted.\n                format: int64\n                type: integer\n            required:\n            - endpoints\n            - selector\n            type: object\n          status:\n            description: |-\n              This Status subresource is under active development and is updated only when the\n              \"StatusForConfigurationResources\" feature gate is enabled.\n\n              Most recent observed status of the ServiceMonitor. Read-only.\n              More info:\n              https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n            properties:\n              bindings:\n                description: The list of workload resources (Prometheus or PrometheusAgent) which select the configuration resource.\n                items:\n                  description: WorkloadBinding is a link between a configuration resource and a workload resource.\n                  properties:\n                    conditions:\n                      description: The current state of the configuration resource when bound to the referenced Prometheus object.\n                      items:\n                        description: ConfigResourceCondition describes the status of configuration resources linked to Prometheus, PrometheusAgent, Alertmanager, or ThanosRuler.\n                        properties:\n                          lastTransitionTime:\n                            description: LastTransitionTime is the time of the last update to the current status property.\n                            format: date-time\n                            type: string\n                          message:\n                            description: Human-readable message indicating details for the condition's last transition.\n                            type: string\n                          observedGeneration:\n                            description: |-\n                              ObservedGeneration represents the .metadata.generation that the\n                              condition was set based upon. For instance, if `.metadata.generation` is\n                              currently 12, but the `.status.conditions[].observedGeneration` is 9, the\n                              condition is out of date with respect to the current state of the object.\n                            format: int64\n                            type: integer\n                          reason:\n                            description: Reason for the condition's last transition.\n                            type: string\n                          status:\n                            description: Status of the condition.\n                            minLength: 1\n                            type: string\n                          type:\n                            description: |-\n                              Type of the condition being reported.\n                              Currently, only \"Accepted\" is supported.\n                            enum:\n                            - Accepted\n                            minLength: 1\n                            type: string\n                        required:\n                        - lastTransitionTime\n                        - status\n                        - type\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - type\n                      x-kubernetes-list-type: map\n                    group:\n                      description: The group of the referenced resource.\n                      enum:\n                      - monitoring.coreos.com\n                      type: string\n                    name:\n                      description: The name of the referenced object.\n                      minLength: 1\n                      type: string\n                    namespace:\n                      description: The namespace of the referenced object.\n                      minLength: 1\n                      type: string\n                    resource:\n                      description: The type of resource being referenced (e.g. Prometheus or PrometheusAgent).\n                      enum:\n                      - prometheuses\n                      - prometheusagents\n                      type: string\n                  required:\n                  - group\n                  - name\n                  - namespace\n                  - resource\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - group\n                - resource\n                - name\n                - namespace\n                x-kubernetes-list-type: map\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n"
  },
  {
    "path": "hack/config/monitoring/crds/0thanosrulerCustomResourceDefinition.yaml",
    "content": "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.18.0\n    operator.prometheus.io/version: 0.85.0\n  name: thanosrulers.monitoring.coreos.com\nspec:\n  group: monitoring.coreos.com\n  names:\n    categories:\n    - prometheus-operator\n    kind: ThanosRuler\n    listKind: ThanosRulerList\n    plural: thanosrulers\n    shortNames:\n    - ruler\n    singular: thanosruler\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - description: The version of Thanos Ruler\n      jsonPath: .spec.version\n      name: Version\n      type: string\n    - description: The number of desired replicas\n      jsonPath: .spec.replicas\n      name: Replicas\n      type: integer\n    - description: The number of ready replicas\n      jsonPath: .status.availableReplicas\n      name: Ready\n      type: integer\n    - jsonPath: .status.conditions[?(@.type == 'Reconciled')].status\n      name: Reconciled\n      type: string\n    - jsonPath: .status.conditions[?(@.type == 'Available')].status\n      name: Available\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    - description: Whether the resource reconciliation is paused or not\n      jsonPath: .status.paused\n      name: Paused\n      priority: 1\n      type: boolean\n    name: v1\n    schema:\n      openAPIV3Schema:\n        description: |-\n          The `ThanosRuler` custom resource definition (CRD) defines a desired [Thanos Ruler](https://github.com/thanos-io/thanos/blob/main/docs/components/rule.md) setup to run in a Kubernetes cluster.\n\n          A `ThanosRuler` instance requires at least one compatible Prometheus API endpoint (either Thanos Querier or Prometheus services).\n\n          The resource defines via label and namespace selectors which `PrometheusRule` objects should be associated to the deployed Thanos Ruler instances.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: |-\n              Specification of the desired behavior of the ThanosRuler cluster. More info:\n              https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n            properties:\n              additionalArgs:\n                description: |-\n                  AdditionalArgs allows setting additional arguments for the ThanosRuler container.\n                  It is intended for e.g. activating hidden flags which are not supported by\n                  the dedicated configuration options yet. The arguments are passed as-is to the\n                  ThanosRuler container which may cause issues if they are invalid or not supported\n                  by the given ThanosRuler version.\n                  In case of an argument conflict (e.g. an argument which is already set by the\n                  operator itself) or when providing an invalid argument the reconciliation will\n                  fail and an error will be logged.\n                items:\n                  description: Argument as part of the AdditionalArgs list.\n                  properties:\n                    name:\n                      description: Name of the argument, e.g. \"scrape.discovery-reload-interval\".\n                      minLength: 1\n                      type: string\n                    value:\n                      description: Argument value, e.g. 30s. Can be empty for name-only arguments (e.g. --storage.tsdb.no-lockfile)\n                      type: string\n                  required:\n                  - name\n                  type: object\n                type: array\n              affinity:\n                description: If specified, the pod's scheduling constraints.\n                properties:\n                  nodeAffinity:\n                    description: Describes node affinity scheduling rules for the pod.\n                    properties:\n                      preferredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          The scheduler will prefer to schedule pods to nodes that satisfy\n                          the affinity expressions specified by this field, but it may choose\n                          a node that violates one or more of the expressions. The node that is\n                          most preferred is the one with the greatest sum of weights, i.e.\n                          for each node that meets all of the scheduling requirements (resource\n                          request, requiredDuringScheduling affinity expressions, etc.),\n                          compute a sum by iterating through the elements of this field and adding\n                          \"weight\" to the sum if the node matches the corresponding matchExpressions; the\n                          node(s) with the highest sum are the most preferred.\n                        items:\n                          description: |-\n                            An empty preferred scheduling term matches all objects with implicit weight 0\n                            (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).\n                          properties:\n                            preference:\n                              description: A node selector term, associated with the corresponding weight.\n                              properties:\n                                matchExpressions:\n                                  description: A list of node selector requirements by node's labels.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchFields:\n                                  description: A list of node selector requirements by node's fields.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            weight:\n                              description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.\n                              format: int32\n                              type: integer\n                          required:\n                          - preference\n                          - weight\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                      requiredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          If the affinity requirements specified by this field are not met at\n                          scheduling time, the pod will not be scheduled onto the node.\n                          If the affinity requirements specified by this field cease to be met\n                          at some point during pod execution (e.g. due to an update), the system\n                          may or may not try to eventually evict the pod from its node.\n                        properties:\n                          nodeSelectorTerms:\n                            description: Required. A list of node selector terms. The terms are ORed.\n                            items:\n                              description: |-\n                                A null or empty node selector term matches no objects. The requirements of\n                                them are ANDed.\n                                The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.\n                              properties:\n                                matchExpressions:\n                                  description: A list of node selector requirements by node's labels.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchFields:\n                                  description: A list of node selector requirements by node's fields.\n                                  items:\n                                    description: |-\n                                      A node selector requirement is a selector that contains values, a key, and an operator\n                                      that relates the key and values.\n                                    properties:\n                                      key:\n                                        description: The label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          Represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          An array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. If the operator is Gt or Lt, the values\n                                          array must have a single element, which will be interpreted as an integer.\n                                          This array is replaced during a strategic merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                            x-kubernetes-list-type: atomic\n                        required:\n                        - nodeSelectorTerms\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  podAffinity:\n                    description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)).\n                    properties:\n                      preferredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          The scheduler will prefer to schedule pods to nodes that satisfy\n                          the affinity expressions specified by this field, but it may choose\n                          a node that violates one or more of the expressions. The node that is\n                          most preferred is the one with the greatest sum of weights, i.e.\n                          for each node that meets all of the scheduling requirements (resource\n                          request, requiredDuringScheduling affinity expressions, etc.),\n                          compute a sum by iterating through the elements of this field and adding\n                          \"weight\" to the sum if the node has pods which matches the corresponding podAffinityTerm; the\n                          node(s) with the highest sum are the most preferred.\n                        items:\n                          description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)\n                          properties:\n                            podAffinityTerm:\n                              description: Required. A pod affinity term, associated with the corresponding weight.\n                              properties:\n                                labelSelector:\n                                  description: |-\n                                    A label query over a set of resources, in this case pods.\n                                    If it's null, this PodAffinityTerm matches with no Pods.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                matchLabelKeys:\n                                  description: |-\n                                    MatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                    Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                mismatchLabelKeys:\n                                  description: |-\n                                    MismatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                    Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                namespaceSelector:\n                                  description: |-\n                                    A label query over the set of namespaces that the term applies to.\n                                    The term is applied to the union of the namespaces selected by this field\n                                    and the ones listed in the namespaces field.\n                                    null selector and null or empty namespaces list means \"this pod's namespace\".\n                                    An empty selector ({}) matches all namespaces.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                namespaces:\n                                  description: |-\n                                    namespaces specifies a static list of namespace names that the term applies to.\n                                    The term is applied to the union of the namespaces listed in this field\n                                    and the ones selected by namespaceSelector.\n                                    null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                topologyKey:\n                                  description: |-\n                                    This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                    the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                    whose value of the label with key topologyKey matches that of any node on which any of the\n                                    selected pods is running.\n                                    Empty topologyKey is not allowed.\n                                  type: string\n                              required:\n                              - topologyKey\n                              type: object\n                            weight:\n                              description: |-\n                                weight associated with matching the corresponding podAffinityTerm,\n                                in the range 1-100.\n                              format: int32\n                              type: integer\n                          required:\n                          - podAffinityTerm\n                          - weight\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                      requiredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          If the affinity requirements specified by this field are not met at\n                          scheduling time, the pod will not be scheduled onto the node.\n                          If the affinity requirements specified by this field cease to be met\n                          at some point during pod execution (e.g. due to a pod label update), the\n                          system may or may not try to eventually evict the pod from its node.\n                          When there are multiple elements, the lists of nodes corresponding to each\n                          podAffinityTerm are intersected, i.e. all terms must be satisfied.\n                        items:\n                          description: |-\n                            Defines a set of pods (namely those matching the labelSelector\n                            relative to the given namespace(s)) that this pod should be\n                            co-located (affinity) or not co-located (anti-affinity) with,\n                            where co-located is defined as running on a node whose value of\n                            the label with key <topologyKey> matches that of any node on which\n                            a pod of the set of pods is running\n                          properties:\n                            labelSelector:\n                              description: |-\n                                A label query over a set of resources, in this case pods.\n                                If it's null, this PodAffinityTerm matches with no Pods.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            matchLabelKeys:\n                              description: |-\n                                MatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            mismatchLabelKeys:\n                              description: |-\n                                MismatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            namespaceSelector:\n                              description: |-\n                                A label query over the set of namespaces that the term applies to.\n                                The term is applied to the union of the namespaces selected by this field\n                                and the ones listed in the namespaces field.\n                                null selector and null or empty namespaces list means \"this pod's namespace\".\n                                An empty selector ({}) matches all namespaces.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            namespaces:\n                              description: |-\n                                namespaces specifies a static list of namespace names that the term applies to.\n                                The term is applied to the union of the namespaces listed in this field\n                                and the ones selected by namespaceSelector.\n                                null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            topologyKey:\n                              description: |-\n                                This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                whose value of the label with key topologyKey matches that of any node on which any of the\n                                selected pods is running.\n                                Empty topologyKey is not allowed.\n                              type: string\n                          required:\n                          - topologyKey\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                    type: object\n                  podAntiAffinity:\n                    description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)).\n                    properties:\n                      preferredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          The scheduler will prefer to schedule pods to nodes that satisfy\n                          the anti-affinity expressions specified by this field, but it may choose\n                          a node that violates one or more of the expressions. The node that is\n                          most preferred is the one with the greatest sum of weights, i.e.\n                          for each node that meets all of the scheduling requirements (resource\n                          request, requiredDuringScheduling anti-affinity expressions, etc.),\n                          compute a sum by iterating through the elements of this field and adding\n                          \"weight\" to the sum if the node has pods which matches the corresponding podAffinityTerm; the\n                          node(s) with the highest sum are the most preferred.\n                        items:\n                          description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)\n                          properties:\n                            podAffinityTerm:\n                              description: Required. A pod affinity term, associated with the corresponding weight.\n                              properties:\n                                labelSelector:\n                                  description: |-\n                                    A label query over a set of resources, in this case pods.\n                                    If it's null, this PodAffinityTerm matches with no Pods.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                matchLabelKeys:\n                                  description: |-\n                                    MatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                    Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                mismatchLabelKeys:\n                                  description: |-\n                                    MismatchLabelKeys is a set of pod label keys to select which pods will\n                                    be taken into consideration. The keys are used to lookup values from the\n                                    incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                    to select the group of existing pods which pods will be taken into consideration\n                                    for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                    pod labels will be ignored. The default value is empty.\n                                    The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                    Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                namespaceSelector:\n                                  description: |-\n                                    A label query over the set of namespaces that the term applies to.\n                                    The term is applied to the union of the namespaces selected by this field\n                                    and the ones listed in the namespaces field.\n                                    null selector and null or empty namespaces list means \"this pod's namespace\".\n                                    An empty selector ({}) matches all namespaces.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                namespaces:\n                                  description: |-\n                                    namespaces specifies a static list of namespace names that the term applies to.\n                                    The term is applied to the union of the namespaces listed in this field\n                                    and the ones selected by namespaceSelector.\n                                    null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                topologyKey:\n                                  description: |-\n                                    This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                    the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                    whose value of the label with key topologyKey matches that of any node on which any of the\n                                    selected pods is running.\n                                    Empty topologyKey is not allowed.\n                                  type: string\n                              required:\n                              - topologyKey\n                              type: object\n                            weight:\n                              description: |-\n                                weight associated with matching the corresponding podAffinityTerm,\n                                in the range 1-100.\n                              format: int32\n                              type: integer\n                          required:\n                          - podAffinityTerm\n                          - weight\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                      requiredDuringSchedulingIgnoredDuringExecution:\n                        description: |-\n                          If the anti-affinity requirements specified by this field are not met at\n                          scheduling time, the pod will not be scheduled onto the node.\n                          If the anti-affinity requirements specified by this field cease to be met\n                          at some point during pod execution (e.g. due to a pod label update), the\n                          system may or may not try to eventually evict the pod from its node.\n                          When there are multiple elements, the lists of nodes corresponding to each\n                          podAffinityTerm are intersected, i.e. all terms must be satisfied.\n                        items:\n                          description: |-\n                            Defines a set of pods (namely those matching the labelSelector\n                            relative to the given namespace(s)) that this pod should be\n                            co-located (affinity) or not co-located (anti-affinity) with,\n                            where co-located is defined as running on a node whose value of\n                            the label with key <topologyKey> matches that of any node on which\n                            a pod of the set of pods is running\n                          properties:\n                            labelSelector:\n                              description: |-\n                                A label query over a set of resources, in this case pods.\n                                If it's null, this PodAffinityTerm matches with no Pods.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            matchLabelKeys:\n                              description: |-\n                                MatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both matchLabelKeys and labelSelector.\n                                Also, matchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            mismatchLabelKeys:\n                              description: |-\n                                MismatchLabelKeys is a set of pod label keys to select which pods will\n                                be taken into consideration. The keys are used to lookup values from the\n                                incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)`\n                                to select the group of existing pods which pods will be taken into consideration\n                                for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming\n                                pod labels will be ignored. The default value is empty.\n                                The same key is forbidden to exist in both mismatchLabelKeys and labelSelector.\n                                Also, mismatchLabelKeys cannot be set when labelSelector isn't set.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            namespaceSelector:\n                              description: |-\n                                A label query over the set of namespaces that the term applies to.\n                                The term is applied to the union of the namespaces selected by this field\n                                and the ones listed in the namespaces field.\n                                null selector and null or empty namespaces list means \"this pod's namespace\".\n                                An empty selector ({}) matches all namespaces.\n                              properties:\n                                matchExpressions:\n                                  description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                  items:\n                                    description: |-\n                                      A label selector requirement is a selector that contains values, a key, and an operator that\n                                      relates the key and values.\n                                    properties:\n                                      key:\n                                        description: key is the label key that the selector applies to.\n                                        type: string\n                                      operator:\n                                        description: |-\n                                          operator represents a key's relationship to a set of values.\n                                          Valid operators are In, NotIn, Exists and DoesNotExist.\n                                        type: string\n                                      values:\n                                        description: |-\n                                          values is an array of string values. If the operator is In or NotIn,\n                                          the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                          the values array must be empty. This array is replaced during a strategic\n                                          merge patch.\n                                        items:\n                                          type: string\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                    required:\n                                    - key\n                                    - operator\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                matchLabels:\n                                  additionalProperties:\n                                    type: string\n                                  description: |-\n                                    matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                    map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                    operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                  type: object\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            namespaces:\n                              description: |-\n                                namespaces specifies a static list of namespace names that the term applies to.\n                                The term is applied to the union of the namespaces listed in this field\n                                and the ones selected by namespaceSelector.\n                                null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            topologyKey:\n                              description: |-\n                                This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching\n                                the labelSelector in the specified namespaces, where co-located is defined as running on a node\n                                whose value of the label with key topologyKey matches that of any node on which any of the\n                                selected pods is running.\n                                Empty topologyKey is not allowed.\n                              type: string\n                          required:\n                          - topologyKey\n                          type: object\n                        type: array\n                        x-kubernetes-list-type: atomic\n                    type: object\n                type: object\n              alertDropLabels:\n                description: |-\n                  Configures the label names which should be dropped in Thanos Ruler\n                  alerts.\n\n                  The replica label `thanos_ruler_replica` will always be dropped from the alerts.\n                items:\n                  type: string\n                type: array\n              alertQueryUrl:\n                description: |-\n                  The external Query URL the Thanos Ruler will set in the 'Source' field\n                  of all alerts.\n                  Maps to the '--alert.query-url' CLI arg.\n                type: string\n              alertRelabelConfigFile:\n                description: |-\n                  Configures the path to the alert relabeling configuration file.\n\n                  Alert relabel configuration must have the form as specified in the\n                  official Prometheus documentation:\n                  https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alert_relabel_configs\n\n                  The operator performs no validation of the configuration file.\n\n                  This field takes precedence over `alertRelabelConfig`.\n                type: string\n              alertRelabelConfigs:\n                description: |-\n                  Configures alert relabeling in Thanos Ruler.\n\n                  Alert relabel configuration must have the form as specified in the\n                  official Prometheus documentation:\n                  https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alert_relabel_configs\n\n                  The operator performs no validation of the configuration.\n\n                  `alertRelabelConfigFile` takes precedence over this field.\n                properties:\n                  key:\n                    description: The key of the secret to select from.  Must be a valid secret key.\n                    type: string\n                  name:\n                    default: \"\"\n                    description: |-\n                      Name of the referent.\n                      This field is effectively required, but due to backwards compatibility is\n                      allowed to be empty. Instances of this type with an empty value here are\n                      almost certainly wrong.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                    type: string\n                  optional:\n                    description: Specify whether the Secret or its key must be defined\n                    type: boolean\n                required:\n                - key\n                type: object\n                x-kubernetes-map-type: atomic\n              alertmanagersConfig:\n                description: |-\n                  Configures the list of Alertmanager endpoints to send alerts to.\n\n                  The configuration format is defined at https://thanos.io/tip/components/rule.md/#alertmanager.\n\n                  It requires Thanos >= v0.10.0.\n\n                  The operator performs no validation of the configuration.\n\n                  This field takes precedence over `alertmanagersUrl`.\n                properties:\n                  key:\n                    description: The key of the secret to select from.  Must be a valid secret key.\n                    type: string\n                  name:\n                    default: \"\"\n                    description: |-\n                      Name of the referent.\n                      This field is effectively required, but due to backwards compatibility is\n                      allowed to be empty. Instances of this type with an empty value here are\n                      almost certainly wrong.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                    type: string\n                  optional:\n                    description: Specify whether the Secret or its key must be defined\n                    type: boolean\n                required:\n                - key\n                type: object\n                x-kubernetes-map-type: atomic\n              alertmanagersUrl:\n                description: |-\n                  Configures the list of Alertmanager endpoints to send alerts to.\n\n                  For Thanos >= v0.10.0, it is recommended to use `alertmanagersConfig` instead.\n\n                  `alertmanagersConfig` takes precedence over this field.\n                items:\n                  type: string\n                type: array\n              containers:\n                description: |-\n                  Containers allows injecting additional containers or modifying operator generated\n                  containers. This can be used to allow adding an authentication proxy to a ThanosRuler pod or\n                  to change the behavior of an operator generated container. Containers described here modify\n                  an operator generated container if they share the same name and modifications are done via a\n                  strategic merge patch. The current container names are: `thanos-ruler` and `config-reloader`.\n                  Overriding containers is entirely outside the scope of what the maintainers will support and by doing\n                  so, you accept that this behaviour may break at any time without notice.\n                items:\n                  description: A single application container that you want to run within a pod.\n                  properties:\n                    args:\n                      description: |-\n                        Arguments to the entrypoint.\n                        The container image's CMD is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    command:\n                      description: |-\n                        Entrypoint array. Not executed within a shell.\n                        The container image's ENTRYPOINT is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    env:\n                      description: |-\n                        List of environment variables to set in the container.\n                        Cannot be updated.\n                      items:\n                        description: EnvVar represents an environment variable present in a Container.\n                        properties:\n                          name:\n                            description: Name of the environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          value:\n                            description: |-\n                              Variable references $(VAR_NAME) are expanded\n                              using the previously defined environment variables in the container and\n                              any service environment variables. If a variable cannot be resolved,\n                              the reference in the input string will be unchanged. Double $$ are reduced\n                              to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.\n                              \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\".\n                              Escaped references will never be expanded, regardless of whether the variable\n                              exists or not.\n                              Defaults to \"\".\n                            type: string\n                          valueFrom:\n                            description: Source for the environment variable's value. Cannot be used if value is not empty.\n                            properties:\n                              configMapKeyRef:\n                                description: Selects a key of a ConfigMap.\n                                properties:\n                                  key:\n                                    description: The key to select.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the ConfigMap or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              fieldRef:\n                                description: |-\n                                  Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,\n                                  spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.\n                                properties:\n                                  apiVersion:\n                                    description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                    type: string\n                                  fieldPath:\n                                    description: Path of the field to select in the specified API version.\n                                    type: string\n                                required:\n                                - fieldPath\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              resourceFieldRef:\n                                description: |-\n                                  Selects a resource of the container: only resources limits and requests\n                                  (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.\n                                properties:\n                                  containerName:\n                                    description: 'Container name: required for volumes, optional for env vars'\n                                    type: string\n                                  divisor:\n                                    anyOf:\n                                    - type: integer\n                                    - type: string\n                                    description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                    x-kubernetes-int-or-string: true\n                                  resource:\n                                    description: 'Required: resource to select'\n                                    type: string\n                                required:\n                                - resource\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              secretKeyRef:\n                                description: Selects a key of a secret in the pod's namespace\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            type: object\n                        required:\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - name\n                      x-kubernetes-list-type: map\n                    envFrom:\n                      description: |-\n                        List of sources to populate environment variables in the container.\n                        The keys defined within a source must be a C_IDENTIFIER. All invalid keys\n                        will be reported as an event when the container is starting. When a key exists in multiple\n                        sources, the value associated with the last source will take precedence.\n                        Values defined by an Env with a duplicate key will take precedence.\n                        Cannot be updated.\n                      items:\n                        description: EnvFromSource represents the source of a set of ConfigMaps or Secrets\n                        properties:\n                          configMapRef:\n                            description: The ConfigMap to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          prefix:\n                            description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          secretRef:\n                            description: The Secret to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    image:\n                      description: |-\n                        Container image name.\n                        More info: https://kubernetes.io/docs/concepts/containers/images\n                        This field is optional to allow higher level config management to default or override\n                        container images in workload controllers like Deployments and StatefulSets.\n                      type: string\n                    imagePullPolicy:\n                      description: |-\n                        Image pull policy.\n                        One of Always, Never, IfNotPresent.\n                        Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/containers/images#updating-images\n                      type: string\n                    lifecycle:\n                      description: |-\n                        Actions that the management system should take in response to container lifecycle events.\n                        Cannot be updated.\n                      properties:\n                        postStart:\n                          description: |-\n                            PostStart is called immediately after a container is created. If the handler fails,\n                            the container is terminated and restarted according to its restart policy.\n                            Other management of the container blocks until the hook completes.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        preStop:\n                          description: |-\n                            PreStop is called immediately before a container is terminated due to an\n                            API request or management event such as liveness/startup probe failure,\n                            preemption, resource contention, etc. The handler is not called if the\n                            container crashes or exits. The Pod's termination grace period countdown begins before the\n                            PreStop hook is executed. Regardless of the outcome of the handler, the\n                            container will eventually terminate within the Pod's termination grace\n                            period (unless delayed by finalizers). Other management of the container blocks until the hook completes\n                            or until the termination grace period is reached.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        stopSignal:\n                          description: |-\n                            StopSignal defines which signal will be sent to a container when it is being stopped.\n                            If not specified, the default is defined by the container runtime in use.\n                            StopSignal can only be set for Pods with a non-empty .spec.os.name\n                          type: string\n                      type: object\n                    livenessProbe:\n                      description: |-\n                        Periodic probe of container liveness.\n                        Container will be restarted if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    name:\n                      description: |-\n                        Name of the container specified as a DNS_LABEL.\n                        Each container in a pod must have a unique name (DNS_LABEL).\n                        Cannot be updated.\n                      type: string\n                    ports:\n                      description: |-\n                        List of ports to expose from the container. Not specifying a port here\n                        DOES NOT prevent that port from being exposed. Any port which is\n                        listening on the default \"0.0.0.0\" address inside a container will be\n                        accessible from the network.\n                        Modifying this array with strategic merge patch may corrupt the data.\n                        For more information See https://github.com/kubernetes/kubernetes/issues/108255.\n                        Cannot be updated.\n                      items:\n                        description: ContainerPort represents a network port in a single container.\n                        properties:\n                          containerPort:\n                            description: |-\n                              Number of port to expose on the pod's IP address.\n                              This must be a valid port number, 0 < x < 65536.\n                            format: int32\n                            type: integer\n                          hostIP:\n                            description: What host IP to bind the external port to.\n                            type: string\n                          hostPort:\n                            description: |-\n                              Number of port to expose on the host.\n                              If specified, this must be a valid port number, 0 < x < 65536.\n                              If HostNetwork is specified, this must match ContainerPort.\n                              Most containers do not need this.\n                            format: int32\n                            type: integer\n                          name:\n                            description: |-\n                              If specified, this must be an IANA_SVC_NAME and unique within the pod. Each\n                              named port in a pod must have a unique name. Name for the port that can be\n                              referred to by services.\n                            type: string\n                          protocol:\n                            default: TCP\n                            description: |-\n                              Protocol for port. Must be UDP, TCP, or SCTP.\n                              Defaults to \"TCP\".\n                            type: string\n                        required:\n                        - containerPort\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - containerPort\n                      - protocol\n                      x-kubernetes-list-type: map\n                    readinessProbe:\n                      description: |-\n                        Periodic probe of container service readiness.\n                        Container will be removed from service endpoints if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    resizePolicy:\n                      description: Resources resize policy for the container.\n                      items:\n                        description: ContainerResizePolicy represents resource resize policy for the container.\n                        properties:\n                          resourceName:\n                            description: |-\n                              Name of the resource to which this resource resize policy applies.\n                              Supported values: cpu, memory.\n                            type: string\n                          restartPolicy:\n                            description: |-\n                              Restart policy to apply when specified resource is resized.\n                              If not specified, it defaults to NotRequired.\n                            type: string\n                        required:\n                        - resourceName\n                        - restartPolicy\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    resources:\n                      description: |-\n                        Compute Resources required by this container.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                      properties:\n                        claims:\n                          description: |-\n                            Claims lists the names of resources, defined in spec.resourceClaims,\n                            that are used by this container.\n\n                            This is an alpha field and requires enabling the\n                            DynamicResourceAllocation feature gate.\n\n                            This field is immutable. It can only be set for containers.\n                          items:\n                            description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                            properties:\n                              name:\n                                description: |-\n                                  Name must match the name of one entry in pod.spec.resourceClaims of\n                                  the Pod where this field is used. It makes that resource available\n                                  inside a container.\n                                type: string\n                              request:\n                                description: |-\n                                  Request is the name chosen for a request in the referenced claim.\n                                  If empty, everything from the claim is made available, otherwise\n                                  only the result of this request.\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          type: array\n                          x-kubernetes-list-map-keys:\n                          - name\n                          x-kubernetes-list-type: map\n                        limits:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Limits describes the maximum amount of compute resources allowed.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                        requests:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Requests describes the minimum amount of compute resources required.\n                            If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                            otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                      type: object\n                    restartPolicy:\n                      description: |-\n                        RestartPolicy defines the restart behavior of individual containers in a pod.\n                        This field may only be set for init containers, and the only allowed value is \"Always\".\n                        For non-init containers or when this field is not specified,\n                        the restart behavior is defined by the Pod's restart policy and the container type.\n                        Setting the RestartPolicy as \"Always\" for the init container will have the following effect:\n                        this init container will be continually restarted on\n                        exit until all regular containers have terminated. Once all regular\n                        containers have completed, all init containers with restartPolicy \"Always\"\n                        will be shut down. This lifecycle differs from normal init containers and\n                        is often referred to as a \"sidecar\" container. Although this init\n                        container still starts in the init container sequence, it does not wait\n                        for the container to complete before proceeding to the next init\n                        container. Instead, the next init container starts immediately after this\n                        init container is started, or after any startupProbe has successfully\n                        completed.\n                      type: string\n                    securityContext:\n                      description: |-\n                        SecurityContext defines the security options the container should be run with.\n                        If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.\n                        More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/\n                      properties:\n                        allowPrivilegeEscalation:\n                          description: |-\n                            AllowPrivilegeEscalation controls whether a process can gain more\n                            privileges than its parent process. This bool directly controls if\n                            the no_new_privs flag will be set on the container process.\n                            AllowPrivilegeEscalation is true always when the container is:\n                            1) run as Privileged\n                            2) has CAP_SYS_ADMIN\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        appArmorProfile:\n                          description: |-\n                            appArmorProfile is the AppArmor options to use by this container. If set, this profile\n                            overrides the pod's appArmorProfile.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile loaded on the node that should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must match the loaded name of the profile.\n                                Must be set if and only if type is \"Localhost\".\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of AppArmor profile will be applied.\n                                Valid options are:\n                                  Localhost - a profile pre-loaded on the node.\n                                  RuntimeDefault - the container runtime's default profile.\n                                  Unconfined - no AppArmor enforcement.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        capabilities:\n                          description: |-\n                            The capabilities to add/drop when running containers.\n                            Defaults to the default set of capabilities granted by the container runtime.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            add:\n                              description: Added capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            drop:\n                              description: Removed capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        privileged:\n                          description: |-\n                            Run container in privileged mode.\n                            Processes in privileged containers are essentially equivalent to root on the host.\n                            Defaults to false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        procMount:\n                          description: |-\n                            procMount denotes the type of proc mount to use for the containers.\n                            The default value is Default which uses the container runtime defaults for\n                            readonly paths and masked paths.\n                            This requires the ProcMountType feature flag to be enabled.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: string\n                        readOnlyRootFilesystem:\n                          description: |-\n                            Whether this container has a read-only root filesystem.\n                            Default is false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        runAsGroup:\n                          description: |-\n                            The GID to run the entrypoint of the container process.\n                            Uses runtime default if unset.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        runAsNonRoot:\n                          description: |-\n                            Indicates that the container must run as a non-root user.\n                            If true, the Kubelet will validate the image at runtime to ensure that it\n                            does not run as UID 0 (root) and fail to start the container if it does.\n                            If unset or false, no such validation will be performed.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                          type: boolean\n                        runAsUser:\n                          description: |-\n                            The UID to run the entrypoint of the container process.\n                            Defaults to user specified in image metadata if unspecified.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        seLinuxOptions:\n                          description: |-\n                            The SELinux context to be applied to the container.\n                            If unspecified, the container runtime will allocate a random SELinux context for each\n                            container.  May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            level:\n                              description: Level is SELinux level label that applies to the container.\n                              type: string\n                            role:\n                              description: Role is a SELinux role label that applies to the container.\n                              type: string\n                            type:\n                              description: Type is a SELinux type label that applies to the container.\n                              type: string\n                            user:\n                              description: User is a SELinux user label that applies to the container.\n                              type: string\n                          type: object\n                        seccompProfile:\n                          description: |-\n                            The seccomp options to use by this container. If seccomp options are\n                            provided at both the pod & container level, the container options\n                            override the pod options.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile defined in a file on the node should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must be a descending path, relative to the kubelet's configured seccomp profile location.\n                                Must be set if type is \"Localhost\". Must NOT be set for any other type.\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of seccomp profile will be applied.\n                                Valid options are:\n\n                                Localhost - a profile defined in a file on the node should be used.\n                                RuntimeDefault - the container runtime default profile should be used.\n                                Unconfined - no profile should be applied.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        windowsOptions:\n                          description: |-\n                            The Windows specific settings applied to all containers.\n                            If unspecified, the options from the PodSecurityContext will be used.\n                            If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is linux.\n                          properties:\n                            gmsaCredentialSpec:\n                              description: |-\n                                GMSACredentialSpec is where the GMSA admission webhook\n                                (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the\n                                GMSA credential spec named by the GMSACredentialSpecName field.\n                              type: string\n                            gmsaCredentialSpecName:\n                              description: GMSACredentialSpecName is the name of the GMSA credential spec to use.\n                              type: string\n                            hostProcess:\n                              description: |-\n                                HostProcess determines if a container should be run as a 'Host Process' container.\n                                All of a Pod's containers must have the same effective HostProcess value\n                                (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).\n                                In addition, if HostProcess is true then HostNetwork must also be set to true.\n                              type: boolean\n                            runAsUserName:\n                              description: |-\n                                The UserName in Windows to run the entrypoint of the container process.\n                                Defaults to the user specified in image metadata if unspecified.\n                                May also be set in PodSecurityContext. If set in both SecurityContext and\n                                PodSecurityContext, the value specified in SecurityContext takes precedence.\n                              type: string\n                          type: object\n                      type: object\n                    startupProbe:\n                      description: |-\n                        StartupProbe indicates that the Pod has successfully initialized.\n                        If specified, no other probes are executed until this completes successfully.\n                        If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.\n                        This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,\n                        when it might take a long time to load data or warm a cache, than during steady-state operation.\n                        This cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    stdin:\n                      description: |-\n                        Whether this container should allocate a buffer for stdin in the container runtime. If this\n                        is not set, reads from stdin in the container will always result in EOF.\n                        Default is false.\n                      type: boolean\n                    stdinOnce:\n                      description: |-\n                        Whether the container runtime should close the stdin channel after it has been opened by\n                        a single attach. When stdin is true the stdin stream will remain open across multiple attach\n                        sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the\n                        first client attaches to stdin, and then remains open and accepts data until the client disconnects,\n                        at which time stdin is closed and remains closed until the container is restarted. If this\n                        flag is false, a container processes that reads from stdin will never receive an EOF.\n                        Default is false\n                      type: boolean\n                    terminationMessagePath:\n                      description: |-\n                        Optional: Path at which the file to which the container's termination message\n                        will be written is mounted into the container's filesystem.\n                        Message written is intended to be brief final status, such as an assertion failure message.\n                        Will be truncated by the node if greater than 4096 bytes. The total message length across\n                        all containers will be limited to 12kb.\n                        Defaults to /dev/termination-log.\n                        Cannot be updated.\n                      type: string\n                    terminationMessagePolicy:\n                      description: |-\n                        Indicate how the termination message should be populated. File will use the contents of\n                        terminationMessagePath to populate the container status message on both success and failure.\n                        FallbackToLogsOnError will use the last chunk of container log output if the termination\n                        message file is empty and the container exited with an error.\n                        The log output is limited to 2048 bytes or 80 lines, whichever is smaller.\n                        Defaults to File.\n                        Cannot be updated.\n                      type: string\n                    tty:\n                      description: |-\n                        Whether this container should allocate a TTY for itself, also requires 'stdin' to be true.\n                        Default is false.\n                      type: boolean\n                    volumeDevices:\n                      description: volumeDevices is the list of block devices to be used by the container.\n                      items:\n                        description: volumeDevice describes a mapping of a raw block device within a container.\n                        properties:\n                          devicePath:\n                            description: devicePath is the path inside of the container that the device will be mapped to.\n                            type: string\n                          name:\n                            description: name must match the name of a persistentVolumeClaim in the pod\n                            type: string\n                        required:\n                        - devicePath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - devicePath\n                      x-kubernetes-list-type: map\n                    volumeMounts:\n                      description: |-\n                        Pod volumes to mount into the container's filesystem.\n                        Cannot be updated.\n                      items:\n                        description: VolumeMount describes a mounting of a Volume within a container.\n                        properties:\n                          mountPath:\n                            description: |-\n                              Path within the container at which the volume should be mounted.  Must\n                              not contain ':'.\n                            type: string\n                          mountPropagation:\n                            description: |-\n                              mountPropagation determines how mounts are propagated from the host\n                              to container and the other way around.\n                              When not set, MountPropagationNone is used.\n                              This field is beta in 1.10.\n                              When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                              (which defaults to None).\n                            type: string\n                          name:\n                            description: This must match the Name of a Volume.\n                            type: string\n                          readOnly:\n                            description: |-\n                              Mounted read-only if true, read-write otherwise (false or unspecified).\n                              Defaults to false.\n                            type: boolean\n                          recursiveReadOnly:\n                            description: |-\n                              RecursiveReadOnly specifies whether read-only mounts should be handled\n                              recursively.\n\n                              If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                              If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                              recursively read-only.  If this field is set to IfPossible, the mount is made\n                              recursively read-only, if it is supported by the container runtime.  If this\n                              field is set to Enabled, the mount is made recursively read-only if it is\n                              supported by the container runtime, otherwise the pod will not be started and\n                              an error will be generated to indicate the reason.\n\n                              If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                              None (or be unspecified, which defaults to None).\n\n                              If this field is not specified, it is treated as an equivalent of Disabled.\n                            type: string\n                          subPath:\n                            description: |-\n                              Path within the volume from which the container's volume should be mounted.\n                              Defaults to \"\" (volume's root).\n                            type: string\n                          subPathExpr:\n                            description: |-\n                              Expanded path within the volume from which the container's volume should be mounted.\n                              Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                              Defaults to \"\" (volume's root).\n                              SubPathExpr and SubPath are mutually exclusive.\n                            type: string\n                        required:\n                        - mountPath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - mountPath\n                      x-kubernetes-list-type: map\n                    workingDir:\n                      description: |-\n                        Container's working directory.\n                        If not specified, the container runtime's default will be used, which\n                        might be configured in the container image.\n                        Cannot be updated.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                type: array\n              dnsConfig:\n                description: Defines the DNS configuration for the pods.\n                properties:\n                  nameservers:\n                    description: |-\n                      A list of DNS name server IP addresses.\n                      This will be appended to the base nameservers generated from DNSPolicy.\n                    items:\n                      minLength: 1\n                      type: string\n                    type: array\n                    x-kubernetes-list-type: set\n                  options:\n                    description: |-\n                      A list of DNS resolver options.\n                      This will be merged with the base options generated from DNSPolicy.\n                      Resolution options given in Options\n                      will override those that appear in the base DNSPolicy.\n                    items:\n                      description: PodDNSConfigOption defines DNS resolver options of a pod.\n                      properties:\n                        name:\n                          description: Name is required and must be unique.\n                          minLength: 1\n                          type: string\n                        value:\n                          description: Value is optional.\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    type: array\n                    x-kubernetes-list-map-keys:\n                    - name\n                    x-kubernetes-list-type: map\n                  searches:\n                    description: |-\n                      A list of DNS search domains for host-name lookup.\n                      This will be appended to the base search paths generated from DNSPolicy.\n                    items:\n                      minLength: 1\n                      type: string\n                    type: array\n                    x-kubernetes-list-type: set\n                type: object\n              dnsPolicy:\n                description: Defines the DNS policy for the pods.\n                enum:\n                - ClusterFirstWithHostNet\n                - ClusterFirst\n                - Default\n                - None\n                type: string\n              enableFeatures:\n                description: |-\n                  Enable access to Thanos Ruler feature flags. By default, no features are enabled.\n\n                  Enabling features which are disabled by default is entirely outside the\n                  scope of what the maintainers will support and by doing so, you accept\n                  that this behaviour may break at any time without notice.\n\n                  For more information see https://thanos.io/tip/components/rule.md/\n\n                  It requires Thanos >= 0.39.0.\n                items:\n                  minLength: 1\n                  type: string\n                type: array\n                x-kubernetes-list-type: set\n              enableServiceLinks:\n                description: Indicates whether information about services should be injected into pod's environment variables\n                type: boolean\n              enforcedNamespaceLabel:\n                description: |-\n                  EnforcedNamespaceLabel enforces adding a namespace label of origin for each alert\n                  and metric that is user created. The label value will always be the namespace of the object that is\n                  being created.\n                type: string\n              evaluationInterval:\n                default: 15s\n                description: Interval between consecutive evaluations.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              excludedFromEnforcement:\n                description: |-\n                  List of references to PrometheusRule objects\n                  to be excluded from enforcing a namespace label of origin.\n                  Applies only if enforcedNamespaceLabel set to true.\n                items:\n                  description: ObjectReference references a PodMonitor, ServiceMonitor, Probe or PrometheusRule object.\n                  properties:\n                    group:\n                      default: monitoring.coreos.com\n                      description: Group of the referent. When not specified, it defaults to `monitoring.coreos.com`\n                      enum:\n                      - monitoring.coreos.com\n                      type: string\n                    name:\n                      description: Name of the referent. When not set, all resources in the namespace are matched.\n                      type: string\n                    namespace:\n                      description: |-\n                        Namespace of the referent.\n                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/\n                      minLength: 1\n                      type: string\n                    resource:\n                      description: Resource of the referent.\n                      enum:\n                      - prometheusrules\n                      - servicemonitors\n                      - podmonitors\n                      - probes\n                      - scrapeconfigs\n                      type: string\n                  required:\n                  - namespace\n                  - resource\n                  type: object\n                type: array\n              externalPrefix:\n                description: |-\n                  The external URL the Thanos Ruler instances will be available under. This is\n                  necessary to generate correct URLs. This is necessary if Thanos Ruler is not\n                  served from root of a DNS name.\n                type: string\n              grpcServerTlsConfig:\n                description: |-\n                  GRPCServerTLSConfig configures the gRPC server from which Thanos Querier reads\n                  recorded rule data.\n                  Note: Currently only the CAFile, CertFile, and KeyFile fields are supported.\n                  Maps to the '--grpc-server-tls-*' CLI args.\n                properties:\n                  ca:\n                    description: Certificate authority used when verifying server certificates.\n                    properties:\n                      configMap:\n                        description: ConfigMap containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key to select.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the ConfigMap or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      secret:\n                        description: Secret containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  caFile:\n                    description: Path to the CA cert in the Prometheus container to use for the targets.\n                    type: string\n                  cert:\n                    description: Client certificate to present when doing client-authentication.\n                    properties:\n                      configMap:\n                        description: ConfigMap containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key to select.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the ConfigMap or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      secret:\n                        description: Secret containing data to use for the targets.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                    type: object\n                  certFile:\n                    description: Path to the client cert file in the Prometheus container for the targets.\n                    type: string\n                  insecureSkipVerify:\n                    description: Disable target certificate validation.\n                    type: boolean\n                  keyFile:\n                    description: Path to the client key file in the Prometheus container for the targets.\n                    type: string\n                  keySecret:\n                    description: Secret containing the client key file for the targets.\n                    properties:\n                      key:\n                        description: The key of the secret to select from.  Must be a valid secret key.\n                        type: string\n                      name:\n                        default: \"\"\n                        description: |-\n                          Name of the referent.\n                          This field is effectively required, but due to backwards compatibility is\n                          allowed to be empty. Instances of this type with an empty value here are\n                          almost certainly wrong.\n                          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                        type: string\n                      optional:\n                        description: Specify whether the Secret or its key must be defined\n                        type: boolean\n                    required:\n                    - key\n                    type: object\n                    x-kubernetes-map-type: atomic\n                  maxVersion:\n                    description: |-\n                      Maximum acceptable TLS version.\n\n                      It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                    enum:\n                    - TLS10\n                    - TLS11\n                    - TLS12\n                    - TLS13\n                    type: string\n                  minVersion:\n                    description: |-\n                      Minimum acceptable TLS version.\n\n                      It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                    enum:\n                    - TLS10\n                    - TLS11\n                    - TLS12\n                    - TLS13\n                    type: string\n                  serverName:\n                    description: Used to verify the hostname for the targets.\n                    type: string\n                type: object\n              hostAliases:\n                description: Pods' hostAliases configuration\n                items:\n                  description: |-\n                    HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the\n                    pod's hosts file.\n                  properties:\n                    hostnames:\n                      description: Hostnames for the above IP address.\n                      items:\n                        type: string\n                      type: array\n                    ip:\n                      description: IP address of the host file entry.\n                      type: string\n                  required:\n                  - hostnames\n                  - ip\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - ip\n                x-kubernetes-list-type: map\n              hostUsers:\n                description: |-\n                  HostUsers supports the user space in Kubernetes.\n\n                  More info: https://kubernetes.io/docs/tasks/configure-pod-container/user-namespaces/\n\n                  The feature requires at least Kubernetes 1.28 with the `UserNamespacesSupport` feature gate enabled.\n                  Starting Kubernetes 1.33, the feature is enabled by default.\n                type: boolean\n              image:\n                description: Thanos container image URL.\n                type: string\n              imagePullPolicy:\n                description: |-\n                  Image pull policy for the 'thanos', 'init-config-reloader' and 'config-reloader' containers.\n                  See https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy for more details.\n                enum:\n                - \"\"\n                - Always\n                - Never\n                - IfNotPresent\n                type: string\n              imagePullSecrets:\n                description: |-\n                  An optional list of references to secrets in the same namespace\n                  to use for pulling thanos images from registries\n                  see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod\n                items:\n                  description: |-\n                    LocalObjectReference contains enough information to let you locate the\n                    referenced object inside the same namespace.\n                  properties:\n                    name:\n                      default: \"\"\n                      description: |-\n                        Name of the referent.\n                        This field is effectively required, but due to backwards compatibility is\n                        allowed to be empty. Instances of this type with an empty value here are\n                        almost certainly wrong.\n                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                      type: string\n                  type: object\n                  x-kubernetes-map-type: atomic\n                type: array\n              initContainers:\n                description: |-\n                  InitContainers allows adding initContainers to the pod definition. Those can be used to e.g.\n                  fetch secrets for injection into the ThanosRuler configuration from external sources. Any\n                  errors during the execution of an initContainer will lead to a restart of the Pod.\n                  More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/\n                  Using initContainers for any use case other then secret fetching is entirely outside the scope\n                  of what the maintainers will support and by doing so, you accept that this behaviour may break\n                  at any time without notice.\n                items:\n                  description: A single application container that you want to run within a pod.\n                  properties:\n                    args:\n                      description: |-\n                        Arguments to the entrypoint.\n                        The container image's CMD is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    command:\n                      description: |-\n                        Entrypoint array. Not executed within a shell.\n                        The container image's ENTRYPOINT is used if this is not provided.\n                        Variable references $(VAR_NAME) are expanded using the container's environment. If a variable\n                        cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced\n                        to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will\n                        produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless\n                        of whether the variable exists or not. Cannot be updated.\n                        More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    env:\n                      description: |-\n                        List of environment variables to set in the container.\n                        Cannot be updated.\n                      items:\n                        description: EnvVar represents an environment variable present in a Container.\n                        properties:\n                          name:\n                            description: Name of the environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          value:\n                            description: |-\n                              Variable references $(VAR_NAME) are expanded\n                              using the previously defined environment variables in the container and\n                              any service environment variables. If a variable cannot be resolved,\n                              the reference in the input string will be unchanged. Double $$ are reduced\n                              to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.\n                              \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\".\n                              Escaped references will never be expanded, regardless of whether the variable\n                              exists or not.\n                              Defaults to \"\".\n                            type: string\n                          valueFrom:\n                            description: Source for the environment variable's value. Cannot be used if value is not empty.\n                            properties:\n                              configMapKeyRef:\n                                description: Selects a key of a ConfigMap.\n                                properties:\n                                  key:\n                                    description: The key to select.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the ConfigMap or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              fieldRef:\n                                description: |-\n                                  Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,\n                                  spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.\n                                properties:\n                                  apiVersion:\n                                    description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                    type: string\n                                  fieldPath:\n                                    description: Path of the field to select in the specified API version.\n                                    type: string\n                                required:\n                                - fieldPath\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              resourceFieldRef:\n                                description: |-\n                                  Selects a resource of the container: only resources limits and requests\n                                  (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.\n                                properties:\n                                  containerName:\n                                    description: 'Container name: required for volumes, optional for env vars'\n                                    type: string\n                                  divisor:\n                                    anyOf:\n                                    - type: integer\n                                    - type: string\n                                    description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                    x-kubernetes-int-or-string: true\n                                  resource:\n                                    description: 'Required: resource to select'\n                                    type: string\n                                required:\n                                - resource\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              secretKeyRef:\n                                description: Selects a key of a secret in the pod's namespace\n                                properties:\n                                  key:\n                                    description: The key of the secret to select from.  Must be a valid secret key.\n                                    type: string\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: Specify whether the Secret or its key must be defined\n                                    type: boolean\n                                required:\n                                - key\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            type: object\n                        required:\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - name\n                      x-kubernetes-list-type: map\n                    envFrom:\n                      description: |-\n                        List of sources to populate environment variables in the container.\n                        The keys defined within a source must be a C_IDENTIFIER. All invalid keys\n                        will be reported as an event when the container is starting. When a key exists in multiple\n                        sources, the value associated with the last source will take precedence.\n                        Values defined by an Env with a duplicate key will take precedence.\n                        Cannot be updated.\n                      items:\n                        description: EnvFromSource represents the source of a set of ConfigMaps or Secrets\n                        properties:\n                          configMapRef:\n                            description: The ConfigMap to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          prefix:\n                            description: Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER.\n                            type: string\n                          secretRef:\n                            description: The Secret to select from\n                            properties:\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret must be defined\n                                type: boolean\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    image:\n                      description: |-\n                        Container image name.\n                        More info: https://kubernetes.io/docs/concepts/containers/images\n                        This field is optional to allow higher level config management to default or override\n                        container images in workload controllers like Deployments and StatefulSets.\n                      type: string\n                    imagePullPolicy:\n                      description: |-\n                        Image pull policy.\n                        One of Always, Never, IfNotPresent.\n                        Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/containers/images#updating-images\n                      type: string\n                    lifecycle:\n                      description: |-\n                        Actions that the management system should take in response to container lifecycle events.\n                        Cannot be updated.\n                      properties:\n                        postStart:\n                          description: |-\n                            PostStart is called immediately after a container is created. If the handler fails,\n                            the container is terminated and restarted according to its restart policy.\n                            Other management of the container blocks until the hook completes.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        preStop:\n                          description: |-\n                            PreStop is called immediately before a container is terminated due to an\n                            API request or management event such as liveness/startup probe failure,\n                            preemption, resource contention, etc. The handler is not called if the\n                            container crashes or exits. The Pod's termination grace period countdown begins before the\n                            PreStop hook is executed. Regardless of the outcome of the handler, the\n                            container will eventually terminate within the Pod's termination grace\n                            period (unless delayed by finalizers). Other management of the container blocks until the hook completes\n                            or until the termination grace period is reached.\n                            More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks\n                          properties:\n                            exec:\n                              description: Exec specifies a command to execute in the container.\n                              properties:\n                                command:\n                                  description: |-\n                                    Command is the command line to execute inside the container, the working directory for the\n                                    command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                    not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                    a shell, you need to explicitly call out to that shell.\n                                    Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                              type: object\n                            httpGet:\n                              description: HTTPGet specifies an HTTP GET request to perform.\n                              properties:\n                                host:\n                                  description: |-\n                                    Host name to connect to, defaults to the pod IP. You probably want to set\n                                    \"Host\" in httpHeaders instead.\n                                  type: string\n                                httpHeaders:\n                                  description: Custom headers to set in the request. HTTP allows repeated headers.\n                                  items:\n                                    description: HTTPHeader describes a custom header to be used in HTTP probes\n                                    properties:\n                                      name:\n                                        description: |-\n                                          The header field name.\n                                          This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                        type: string\n                                      value:\n                                        description: The header field value\n                                        type: string\n                                    required:\n                                    - name\n                                    - value\n                                    type: object\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                path:\n                                  description: Path to access on the HTTP server.\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Name or number of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                                scheme:\n                                  description: |-\n                                    Scheme to use for connecting to the host.\n                                    Defaults to HTTP.\n                                  type: string\n                              required:\n                              - port\n                              type: object\n                            sleep:\n                              description: Sleep represents a duration that the container should sleep.\n                              properties:\n                                seconds:\n                                  description: Seconds is the number of seconds to sleep.\n                                  format: int64\n                                  type: integer\n                              required:\n                              - seconds\n                              type: object\n                            tcpSocket:\n                              description: |-\n                                Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept\n                                for backward compatibility. There is no validation of this field and\n                                lifecycle hooks will fail at runtime when it is specified.\n                              properties:\n                                host:\n                                  description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                                  type: string\n                                port:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  description: |-\n                                    Number or name of the port to access on the container.\n                                    Number must be in the range 1 to 65535.\n                                    Name must be an IANA_SVC_NAME.\n                                  x-kubernetes-int-or-string: true\n                              required:\n                              - port\n                              type: object\n                          type: object\n                        stopSignal:\n                          description: |-\n                            StopSignal defines which signal will be sent to a container when it is being stopped.\n                            If not specified, the default is defined by the container runtime in use.\n                            StopSignal can only be set for Pods with a non-empty .spec.os.name\n                          type: string\n                      type: object\n                    livenessProbe:\n                      description: |-\n                        Periodic probe of container liveness.\n                        Container will be restarted if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    name:\n                      description: |-\n                        Name of the container specified as a DNS_LABEL.\n                        Each container in a pod must have a unique name (DNS_LABEL).\n                        Cannot be updated.\n                      type: string\n                    ports:\n                      description: |-\n                        List of ports to expose from the container. Not specifying a port here\n                        DOES NOT prevent that port from being exposed. Any port which is\n                        listening on the default \"0.0.0.0\" address inside a container will be\n                        accessible from the network.\n                        Modifying this array with strategic merge patch may corrupt the data.\n                        For more information See https://github.com/kubernetes/kubernetes/issues/108255.\n                        Cannot be updated.\n                      items:\n                        description: ContainerPort represents a network port in a single container.\n                        properties:\n                          containerPort:\n                            description: |-\n                              Number of port to expose on the pod's IP address.\n                              This must be a valid port number, 0 < x < 65536.\n                            format: int32\n                            type: integer\n                          hostIP:\n                            description: What host IP to bind the external port to.\n                            type: string\n                          hostPort:\n                            description: |-\n                              Number of port to expose on the host.\n                              If specified, this must be a valid port number, 0 < x < 65536.\n                              If HostNetwork is specified, this must match ContainerPort.\n                              Most containers do not need this.\n                            format: int32\n                            type: integer\n                          name:\n                            description: |-\n                              If specified, this must be an IANA_SVC_NAME and unique within the pod. Each\n                              named port in a pod must have a unique name. Name for the port that can be\n                              referred to by services.\n                            type: string\n                          protocol:\n                            default: TCP\n                            description: |-\n                              Protocol for port. Must be UDP, TCP, or SCTP.\n                              Defaults to \"TCP\".\n                            type: string\n                        required:\n                        - containerPort\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - containerPort\n                      - protocol\n                      x-kubernetes-list-type: map\n                    readinessProbe:\n                      description: |-\n                        Periodic probe of container service readiness.\n                        Container will be removed from service endpoints if the probe fails.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    resizePolicy:\n                      description: Resources resize policy for the container.\n                      items:\n                        description: ContainerResizePolicy represents resource resize policy for the container.\n                        properties:\n                          resourceName:\n                            description: |-\n                              Name of the resource to which this resource resize policy applies.\n                              Supported values: cpu, memory.\n                            type: string\n                          restartPolicy:\n                            description: |-\n                              Restart policy to apply when specified resource is resized.\n                              If not specified, it defaults to NotRequired.\n                            type: string\n                        required:\n                        - resourceName\n                        - restartPolicy\n                        type: object\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    resources:\n                      description: |-\n                        Compute Resources required by this container.\n                        Cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                      properties:\n                        claims:\n                          description: |-\n                            Claims lists the names of resources, defined in spec.resourceClaims,\n                            that are used by this container.\n\n                            This is an alpha field and requires enabling the\n                            DynamicResourceAllocation feature gate.\n\n                            This field is immutable. It can only be set for containers.\n                          items:\n                            description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                            properties:\n                              name:\n                                description: |-\n                                  Name must match the name of one entry in pod.spec.resourceClaims of\n                                  the Pod where this field is used. It makes that resource available\n                                  inside a container.\n                                type: string\n                              request:\n                                description: |-\n                                  Request is the name chosen for a request in the referenced claim.\n                                  If empty, everything from the claim is made available, otherwise\n                                  only the result of this request.\n                                type: string\n                            required:\n                            - name\n                            type: object\n                          type: array\n                          x-kubernetes-list-map-keys:\n                          - name\n                          x-kubernetes-list-type: map\n                        limits:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Limits describes the maximum amount of compute resources allowed.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                        requests:\n                          additionalProperties:\n                            anyOf:\n                            - type: integer\n                            - type: string\n                            pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                            x-kubernetes-int-or-string: true\n                          description: |-\n                            Requests describes the minimum amount of compute resources required.\n                            If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                            otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                            More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                          type: object\n                      type: object\n                    restartPolicy:\n                      description: |-\n                        RestartPolicy defines the restart behavior of individual containers in a pod.\n                        This field may only be set for init containers, and the only allowed value is \"Always\".\n                        For non-init containers or when this field is not specified,\n                        the restart behavior is defined by the Pod's restart policy and the container type.\n                        Setting the RestartPolicy as \"Always\" for the init container will have the following effect:\n                        this init container will be continually restarted on\n                        exit until all regular containers have terminated. Once all regular\n                        containers have completed, all init containers with restartPolicy \"Always\"\n                        will be shut down. This lifecycle differs from normal init containers and\n                        is often referred to as a \"sidecar\" container. Although this init\n                        container still starts in the init container sequence, it does not wait\n                        for the container to complete before proceeding to the next init\n                        container. Instead, the next init container starts immediately after this\n                        init container is started, or after any startupProbe has successfully\n                        completed.\n                      type: string\n                    securityContext:\n                      description: |-\n                        SecurityContext defines the security options the container should be run with.\n                        If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.\n                        More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/\n                      properties:\n                        allowPrivilegeEscalation:\n                          description: |-\n                            AllowPrivilegeEscalation controls whether a process can gain more\n                            privileges than its parent process. This bool directly controls if\n                            the no_new_privs flag will be set on the container process.\n                            AllowPrivilegeEscalation is true always when the container is:\n                            1) run as Privileged\n                            2) has CAP_SYS_ADMIN\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        appArmorProfile:\n                          description: |-\n                            appArmorProfile is the AppArmor options to use by this container. If set, this profile\n                            overrides the pod's appArmorProfile.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile loaded on the node that should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must match the loaded name of the profile.\n                                Must be set if and only if type is \"Localhost\".\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of AppArmor profile will be applied.\n                                Valid options are:\n                                  Localhost - a profile pre-loaded on the node.\n                                  RuntimeDefault - the container runtime's default profile.\n                                  Unconfined - no AppArmor enforcement.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        capabilities:\n                          description: |-\n                            The capabilities to add/drop when running containers.\n                            Defaults to the default set of capabilities granted by the container runtime.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            add:\n                              description: Added capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            drop:\n                              description: Removed capabilities\n                              items:\n                                description: Capability represent POSIX capabilities type\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        privileged:\n                          description: |-\n                            Run container in privileged mode.\n                            Processes in privileged containers are essentially equivalent to root on the host.\n                            Defaults to false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        procMount:\n                          description: |-\n                            procMount denotes the type of proc mount to use for the containers.\n                            The default value is Default which uses the container runtime defaults for\n                            readonly paths and masked paths.\n                            This requires the ProcMountType feature flag to be enabled.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: string\n                        readOnlyRootFilesystem:\n                          description: |-\n                            Whether this container has a read-only root filesystem.\n                            Default is false.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          type: boolean\n                        runAsGroup:\n                          description: |-\n                            The GID to run the entrypoint of the container process.\n                            Uses runtime default if unset.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        runAsNonRoot:\n                          description: |-\n                            Indicates that the container must run as a non-root user.\n                            If true, the Kubelet will validate the image at runtime to ensure that it\n                            does not run as UID 0 (root) and fail to start the container if it does.\n                            If unset or false, no such validation will be performed.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                          type: boolean\n                        runAsUser:\n                          description: |-\n                            The UID to run the entrypoint of the container process.\n                            Defaults to user specified in image metadata if unspecified.\n                            May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          format: int64\n                          type: integer\n                        seLinuxOptions:\n                          description: |-\n                            The SELinux context to be applied to the container.\n                            If unspecified, the container runtime will allocate a random SELinux context for each\n                            container.  May also be set in PodSecurityContext.  If set in both SecurityContext and\n                            PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            level:\n                              description: Level is SELinux level label that applies to the container.\n                              type: string\n                            role:\n                              description: Role is a SELinux role label that applies to the container.\n                              type: string\n                            type:\n                              description: Type is a SELinux type label that applies to the container.\n                              type: string\n                            user:\n                              description: User is a SELinux user label that applies to the container.\n                              type: string\n                          type: object\n                        seccompProfile:\n                          description: |-\n                            The seccomp options to use by this container. If seccomp options are\n                            provided at both the pod & container level, the container options\n                            override the pod options.\n                            Note that this field cannot be set when spec.os.name is windows.\n                          properties:\n                            localhostProfile:\n                              description: |-\n                                localhostProfile indicates a profile defined in a file on the node should be used.\n                                The profile must be preconfigured on the node to work.\n                                Must be a descending path, relative to the kubelet's configured seccomp profile location.\n                                Must be set if type is \"Localhost\". Must NOT be set for any other type.\n                              type: string\n                            type:\n                              description: |-\n                                type indicates which kind of seccomp profile will be applied.\n                                Valid options are:\n\n                                Localhost - a profile defined in a file on the node should be used.\n                                RuntimeDefault - the container runtime default profile should be used.\n                                Unconfined - no profile should be applied.\n                              type: string\n                          required:\n                          - type\n                          type: object\n                        windowsOptions:\n                          description: |-\n                            The Windows specific settings applied to all containers.\n                            If unspecified, the options from the PodSecurityContext will be used.\n                            If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.\n                            Note that this field cannot be set when spec.os.name is linux.\n                          properties:\n                            gmsaCredentialSpec:\n                              description: |-\n                                GMSACredentialSpec is where the GMSA admission webhook\n                                (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the\n                                GMSA credential spec named by the GMSACredentialSpecName field.\n                              type: string\n                            gmsaCredentialSpecName:\n                              description: GMSACredentialSpecName is the name of the GMSA credential spec to use.\n                              type: string\n                            hostProcess:\n                              description: |-\n                                HostProcess determines if a container should be run as a 'Host Process' container.\n                                All of a Pod's containers must have the same effective HostProcess value\n                                (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).\n                                In addition, if HostProcess is true then HostNetwork must also be set to true.\n                              type: boolean\n                            runAsUserName:\n                              description: |-\n                                The UserName in Windows to run the entrypoint of the container process.\n                                Defaults to the user specified in image metadata if unspecified.\n                                May also be set in PodSecurityContext. If set in both SecurityContext and\n                                PodSecurityContext, the value specified in SecurityContext takes precedence.\n                              type: string\n                          type: object\n                      type: object\n                    startupProbe:\n                      description: |-\n                        StartupProbe indicates that the Pod has successfully initialized.\n                        If specified, no other probes are executed until this completes successfully.\n                        If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.\n                        This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,\n                        when it might take a long time to load data or warm a cache, than during steady-state operation.\n                        This cannot be updated.\n                        More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                      properties:\n                        exec:\n                          description: Exec specifies a command to execute in the container.\n                          properties:\n                            command:\n                              description: |-\n                                Command is the command line to execute inside the container, the working directory for the\n                                command  is root ('/') in the container's filesystem. The command is simply exec'd, it is\n                                not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use\n                                a shell, you need to explicitly call out to that shell.\n                                Exit status of 0 is treated as live/healthy and non-zero is unhealthy.\n                              items:\n                                type: string\n                              type: array\n                              x-kubernetes-list-type: atomic\n                          type: object\n                        failureThreshold:\n                          description: |-\n                            Minimum consecutive failures for the probe to be considered failed after having succeeded.\n                            Defaults to 3. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        grpc:\n                          description: GRPC specifies a GRPC HealthCheckRequest.\n                          properties:\n                            port:\n                              description: Port number of the gRPC service. Number must be in the range 1 to 65535.\n                              format: int32\n                              type: integer\n                            service:\n                              default: \"\"\n                              description: |-\n                                Service is the name of the service to place in the gRPC HealthCheckRequest\n                                (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).\n\n                                If this is not specified, the default behavior is defined by gRPC.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        httpGet:\n                          description: HTTPGet specifies an HTTP GET request to perform.\n                          properties:\n                            host:\n                              description: |-\n                                Host name to connect to, defaults to the pod IP. You probably want to set\n                                \"Host\" in httpHeaders instead.\n                              type: string\n                            httpHeaders:\n                              description: Custom headers to set in the request. HTTP allows repeated headers.\n                              items:\n                                description: HTTPHeader describes a custom header to be used in HTTP probes\n                                properties:\n                                  name:\n                                    description: |-\n                                      The header field name.\n                                      This will be canonicalized upon output, so case-variant names will be understood as the same header.\n                                    type: string\n                                  value:\n                                    description: The header field value\n                                    type: string\n                                required:\n                                - name\n                                - value\n                                type: object\n                              type: array\n                              x-kubernetes-list-type: atomic\n                            path:\n                              description: Path to access on the HTTP server.\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Name or number of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                            scheme:\n                              description: |-\n                                Scheme to use for connecting to the host.\n                                Defaults to HTTP.\n                              type: string\n                          required:\n                          - port\n                          type: object\n                        initialDelaySeconds:\n                          description: |-\n                            Number of seconds after the container has started before liveness probes are initiated.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                        periodSeconds:\n                          description: |-\n                            How often (in seconds) to perform the probe.\n                            Default to 10 seconds. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        successThreshold:\n                          description: |-\n                            Minimum consecutive successes for the probe to be considered successful after having failed.\n                            Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.\n                          format: int32\n                          type: integer\n                        tcpSocket:\n                          description: TCPSocket specifies a connection to a TCP port.\n                          properties:\n                            host:\n                              description: 'Optional: Host name to connect to, defaults to the pod IP.'\n                              type: string\n                            port:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              description: |-\n                                Number or name of the port to access on the container.\n                                Number must be in the range 1 to 65535.\n                                Name must be an IANA_SVC_NAME.\n                              x-kubernetes-int-or-string: true\n                          required:\n                          - port\n                          type: object\n                        terminationGracePeriodSeconds:\n                          description: |-\n                            Optional duration in seconds the pod needs to terminate gracefully upon probe failure.\n                            The grace period is the duration in seconds after the processes running in the pod are sent\n                            a termination signal and the time when the processes are forcibly halted with a kill signal.\n                            Set this value longer than the expected cleanup time for your process.\n                            If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this\n                            value overrides the value provided by the pod spec.\n                            Value must be non-negative integer. The value zero indicates stop immediately via\n                            the kill signal (no opportunity to shut down).\n                            This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.\n                            Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.\n                          format: int64\n                          type: integer\n                        timeoutSeconds:\n                          description: |-\n                            Number of seconds after which the probe times out.\n                            Defaults to 1 second. Minimum value is 1.\n                            More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes\n                          format: int32\n                          type: integer\n                      type: object\n                    stdin:\n                      description: |-\n                        Whether this container should allocate a buffer for stdin in the container runtime. If this\n                        is not set, reads from stdin in the container will always result in EOF.\n                        Default is false.\n                      type: boolean\n                    stdinOnce:\n                      description: |-\n                        Whether the container runtime should close the stdin channel after it has been opened by\n                        a single attach. When stdin is true the stdin stream will remain open across multiple attach\n                        sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the\n                        first client attaches to stdin, and then remains open and accepts data until the client disconnects,\n                        at which time stdin is closed and remains closed until the container is restarted. If this\n                        flag is false, a container processes that reads from stdin will never receive an EOF.\n                        Default is false\n                      type: boolean\n                    terminationMessagePath:\n                      description: |-\n                        Optional: Path at which the file to which the container's termination message\n                        will be written is mounted into the container's filesystem.\n                        Message written is intended to be brief final status, such as an assertion failure message.\n                        Will be truncated by the node if greater than 4096 bytes. The total message length across\n                        all containers will be limited to 12kb.\n                        Defaults to /dev/termination-log.\n                        Cannot be updated.\n                      type: string\n                    terminationMessagePolicy:\n                      description: |-\n                        Indicate how the termination message should be populated. File will use the contents of\n                        terminationMessagePath to populate the container status message on both success and failure.\n                        FallbackToLogsOnError will use the last chunk of container log output if the termination\n                        message file is empty and the container exited with an error.\n                        The log output is limited to 2048 bytes or 80 lines, whichever is smaller.\n                        Defaults to File.\n                        Cannot be updated.\n                      type: string\n                    tty:\n                      description: |-\n                        Whether this container should allocate a TTY for itself, also requires 'stdin' to be true.\n                        Default is false.\n                      type: boolean\n                    volumeDevices:\n                      description: volumeDevices is the list of block devices to be used by the container.\n                      items:\n                        description: volumeDevice describes a mapping of a raw block device within a container.\n                        properties:\n                          devicePath:\n                            description: devicePath is the path inside of the container that the device will be mapped to.\n                            type: string\n                          name:\n                            description: name must match the name of a persistentVolumeClaim in the pod\n                            type: string\n                        required:\n                        - devicePath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - devicePath\n                      x-kubernetes-list-type: map\n                    volumeMounts:\n                      description: |-\n                        Pod volumes to mount into the container's filesystem.\n                        Cannot be updated.\n                      items:\n                        description: VolumeMount describes a mounting of a Volume within a container.\n                        properties:\n                          mountPath:\n                            description: |-\n                              Path within the container at which the volume should be mounted.  Must\n                              not contain ':'.\n                            type: string\n                          mountPropagation:\n                            description: |-\n                              mountPropagation determines how mounts are propagated from the host\n                              to container and the other way around.\n                              When not set, MountPropagationNone is used.\n                              This field is beta in 1.10.\n                              When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                              (which defaults to None).\n                            type: string\n                          name:\n                            description: This must match the Name of a Volume.\n                            type: string\n                          readOnly:\n                            description: |-\n                              Mounted read-only if true, read-write otherwise (false or unspecified).\n                              Defaults to false.\n                            type: boolean\n                          recursiveReadOnly:\n                            description: |-\n                              RecursiveReadOnly specifies whether read-only mounts should be handled\n                              recursively.\n\n                              If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                              If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                              recursively read-only.  If this field is set to IfPossible, the mount is made\n                              recursively read-only, if it is supported by the container runtime.  If this\n                              field is set to Enabled, the mount is made recursively read-only if it is\n                              supported by the container runtime, otherwise the pod will not be started and\n                              an error will be generated to indicate the reason.\n\n                              If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                              None (or be unspecified, which defaults to None).\n\n                              If this field is not specified, it is treated as an equivalent of Disabled.\n                            type: string\n                          subPath:\n                            description: |-\n                              Path within the volume from which the container's volume should be mounted.\n                              Defaults to \"\" (volume's root).\n                            type: string\n                          subPathExpr:\n                            description: |-\n                              Expanded path within the volume from which the container's volume should be mounted.\n                              Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                              Defaults to \"\" (volume's root).\n                              SubPathExpr and SubPath are mutually exclusive.\n                            type: string\n                        required:\n                        - mountPath\n                        - name\n                        type: object\n                      type: array\n                      x-kubernetes-list-map-keys:\n                      - mountPath\n                      x-kubernetes-list-type: map\n                    workingDir:\n                      description: |-\n                        Container's working directory.\n                        If not specified, the container runtime's default will be used, which\n                        might be configured in the container image.\n                        Cannot be updated.\n                      type: string\n                  required:\n                  - name\n                  type: object\n                type: array\n              labels:\n                additionalProperties:\n                  type: string\n                description: |-\n                  Configures the external label pairs of the ThanosRuler resource.\n\n                  A default replica label `thanos_ruler_replica` will be always added as a\n                  label with the value of the pod's name.\n                type: object\n              listenLocal:\n                description: |-\n                  ListenLocal makes the Thanos ruler listen on loopback, so that it\n                  does not bind against the Pod IP.\n                type: boolean\n              logFormat:\n                description: Log format for ThanosRuler to be configured with.\n                enum:\n                - \"\"\n                - logfmt\n                - json\n                type: string\n              logLevel:\n                description: Log level for ThanosRuler to be configured with.\n                enum:\n                - \"\"\n                - debug\n                - info\n                - warn\n                - error\n                type: string\n              minReadySeconds:\n                description: |-\n                  Minimum number of seconds for which a newly created pod should be ready\n                  without any of its container crashing for it to be considered available.\n\n                  If unset, pods will be considered available as soon as they are ready.\n                format: int32\n                minimum: 0\n                type: integer\n              nodeSelector:\n                additionalProperties:\n                  type: string\n                description: Define which Nodes the Pods are scheduled on.\n                type: object\n              objectStorageConfig:\n                description: |-\n                  Configures object storage.\n\n                  The configuration format is defined at https://thanos.io/tip/thanos/storage.md/#configuring-access-to-object-storage\n\n                  The operator performs no validation of the configuration.\n\n                  `objectStorageConfigFile` takes precedence over this field.\n                properties:\n                  key:\n                    description: The key of the secret to select from.  Must be a valid secret key.\n                    type: string\n                  name:\n                    default: \"\"\n                    description: |-\n                      Name of the referent.\n                      This field is effectively required, but due to backwards compatibility is\n                      allowed to be empty. Instances of this type with an empty value here are\n                      almost certainly wrong.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                    type: string\n                  optional:\n                    description: Specify whether the Secret or its key must be defined\n                    type: boolean\n                required:\n                - key\n                type: object\n                x-kubernetes-map-type: atomic\n              objectStorageConfigFile:\n                description: |-\n                  Configures the path of the object storage configuration file.\n\n                  The configuration format is defined at https://thanos.io/tip/thanos/storage.md/#configuring-access-to-object-storage\n\n                  The operator performs no validation of the configuration file.\n\n                  This field takes precedence over `objectStorageConfig`.\n                type: string\n              paused:\n                description: |-\n                  When a ThanosRuler deployment is paused, no actions except for deletion\n                  will be performed on the underlying objects.\n                type: boolean\n              podMetadata:\n                description: |-\n                  PodMetadata configures labels and annotations which are propagated to the ThanosRuler pods.\n\n                  The following items are reserved and cannot be overridden:\n                  * \"app.kubernetes.io/name\" label, set to \"thanos-ruler\".\n                  * \"app.kubernetes.io/managed-by\" label, set to \"prometheus-operator\".\n                  * \"app.kubernetes.io/instance\" label, set to the name of the ThanosRuler instance.\n                  * \"thanos-ruler\" label, set to the name of the ThanosRuler instance.\n                  * \"kubectl.kubernetes.io/default-container\" annotation, set to \"thanos-ruler\".\n                properties:\n                  annotations:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      Annotations is an unstructured key value map stored with a resource that may be\n                      set by external tools to store and retrieve arbitrary metadata. They are not\n                      queryable and should be preserved when modifying objects.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/\n                    type: object\n                  labels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      Map of string keys and values that can be used to organize and categorize\n                      (scope and select) objects. May match selectors of replication controllers\n                      and services.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/\n                    type: object\n                  name:\n                    description: |-\n                      Name must be unique within a namespace. Is required when creating resources, although\n                      some resources may allow a client to request the generation of an appropriate name\n                      automatically. Name is primarily intended for creation idempotence and configuration\n                      definition.\n                      Cannot be updated.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\n                    type: string\n                type: object\n              portName:\n                default: web\n                description: |-\n                  Port name used for the pods and governing service.\n                  Defaults to `web`.\n                type: string\n              priorityClassName:\n                description: Priority class assigned to the Pods\n                type: string\n              prometheusRulesExcludedFromEnforce:\n                description: |-\n                  PrometheusRulesExcludedFromEnforce - list of Prometheus rules to be excluded from enforcing\n                  of adding namespace labels. Works only if enforcedNamespaceLabel set to true.\n                  Make sure both ruleNamespace and ruleName are set for each pair\n                  Deprecated: use excludedFromEnforcement instead.\n                items:\n                  description: |-\n                    PrometheusRuleExcludeConfig enables users to configure excluded\n                    PrometheusRule names and their namespaces to be ignored while enforcing\n                    namespace label for alerts and metrics.\n                  properties:\n                    ruleName:\n                      description: Name of the excluded PrometheusRule object.\n                      type: string\n                    ruleNamespace:\n                      description: Namespace of the excluded PrometheusRule object.\n                      type: string\n                  required:\n                  - ruleName\n                  - ruleNamespace\n                  type: object\n                type: array\n              queryConfig:\n                description: |-\n                  Configures the list of Thanos Query endpoints from which to query metrics.\n\n                  The configuration format is defined at https://thanos.io/tip/components/rule.md/#query-api\n\n                  It requires Thanos >= v0.11.0.\n\n                  The operator performs no validation of the configuration.\n\n                  This field takes precedence over `queryEndpoints`.\n                properties:\n                  key:\n                    description: The key of the secret to select from.  Must be a valid secret key.\n                    type: string\n                  name:\n                    default: \"\"\n                    description: |-\n                      Name of the referent.\n                      This field is effectively required, but due to backwards compatibility is\n                      allowed to be empty. Instances of this type with an empty value here are\n                      almost certainly wrong.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                    type: string\n                  optional:\n                    description: Specify whether the Secret or its key must be defined\n                    type: boolean\n                required:\n                - key\n                type: object\n                x-kubernetes-map-type: atomic\n              queryEndpoints:\n                description: |-\n                  Configures the list of Thanos Query endpoints from which to query metrics.\n\n                  For Thanos >= v0.11.0, it is recommended to use `queryConfig` instead.\n\n                  `queryConfig` takes precedence over this field.\n                items:\n                  type: string\n                type: array\n              remoteWrite:\n                description: |-\n                  Defines the list of remote write configurations.\n\n                  When the list isn't empty, the ruler is configured with stateless mode.\n\n                  It requires Thanos >= 0.24.0.\n                items:\n                  description: |-\n                    RemoteWriteSpec defines the configuration to write samples from Prometheus\n                    to a remote endpoint.\n                  properties:\n                    authorization:\n                      description: |-\n                        Authorization section for the URL.\n\n                        It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0.\n\n                        Cannot be set at the same time as `sigv4`, `basicAuth`, `oauth2`, or `azureAd`.\n                      properties:\n                        credentials:\n                          description: Selects a key of a Secret in the namespace that contains the credentials for authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        credentialsFile:\n                          description: File to read a secret from, mutually exclusive with `credentials`.\n                          type: string\n                        type:\n                          description: |-\n                            Defines the authentication type. The value is case-insensitive.\n\n                            \"Basic\" is not a supported value.\n\n                            Default: \"Bearer\"\n                          type: string\n                      type: object\n                    azureAd:\n                      description: |-\n                        AzureAD for the URL.\n\n                        It requires Prometheus >= v2.45.0 or Thanos >= v0.31.0.\n\n                        Cannot be set at the same time as `authorization`, `basicAuth`, `oauth2`, or `sigv4`.\n                      properties:\n                        cloud:\n                          description: The Azure Cloud. Options are 'AzurePublic', 'AzureChina', or 'AzureGovernment'.\n                          enum:\n                          - AzureChina\n                          - AzureGovernment\n                          - AzurePublic\n                          type: string\n                        managedIdentity:\n                          description: |-\n                            ManagedIdentity defines the Azure User-assigned Managed identity.\n                            Cannot be set at the same time as `oauth` or `sdk`.\n                          properties:\n                            clientId:\n                              description: The client id\n                              type: string\n                          required:\n                          - clientId\n                          type: object\n                        oauth:\n                          description: |-\n                            OAuth defines the oauth config that is being used to authenticate.\n                            Cannot be set at the same time as `managedIdentity` or `sdk`.\n\n                            It requires Prometheus >= v2.48.0 or Thanos >= v0.31.0.\n                          properties:\n                            clientId:\n                              description: '`clientID` is the clientId of the Azure Active Directory application that is being used to authenticate.'\n                              minLength: 1\n                              type: string\n                            clientSecret:\n                              description: '`clientSecret` specifies a key of a Secret containing the client secret of the Azure Active Directory application that is being used to authenticate.'\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            tenantId:\n                              description: '`tenantId` is the tenant ID of the Azure Active Directory application that is being used to authenticate.'\n                              minLength: 1\n                              pattern: ^[0-9a-zA-Z-.]+$\n                              type: string\n                          required:\n                          - clientId\n                          - clientSecret\n                          - tenantId\n                          type: object\n                        sdk:\n                          description: |-\n                            SDK defines the Azure SDK config that is being used to authenticate.\n                            See https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication\n                            Cannot be set at the same time as `oauth` or `managedIdentity`.\n\n                            It requires Prometheus >= v2.52.0 or Thanos >= v0.36.0.\n                          properties:\n                            tenantId:\n                              description: '`tenantId` is the tenant ID of the azure active directory application that is being used to authenticate.'\n                              pattern: ^[0-9a-zA-Z-.]+$\n                              type: string\n                          type: object\n                      type: object\n                    basicAuth:\n                      description: |-\n                        BasicAuth configuration for the URL.\n\n                        Cannot be set at the same time as `sigv4`, `authorization`, `oauth2`, or `azureAd`.\n                      properties:\n                        password:\n                          description: |-\n                            `password` specifies a key of a Secret containing the password for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        username:\n                          description: |-\n                            `username` specifies a key of a Secret containing the username for\n                            authentication.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    bearerToken:\n                      description: |-\n                        *Warning: this field shouldn't be used because the token value appears\n                        in clear-text. Prefer using `authorization`.*\n\n                        Deprecated: this will be removed in a future release.\n                      type: string\n                    bearerTokenFile:\n                      description: |-\n                        File from which to read bearer token for the URL.\n\n                        Deprecated: this will be removed in a future release. Prefer using `authorization`.\n                      type: string\n                    enableHTTP2:\n                      description: Whether to enable HTTP2.\n                      type: boolean\n                    followRedirects:\n                      description: |-\n                        Configure whether HTTP requests follow HTTP 3xx redirects.\n\n                        It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0.\n                      type: boolean\n                    headers:\n                      additionalProperties:\n                        type: string\n                      description: |-\n                        Custom HTTP headers to be sent along with each remote write request.\n                        Be aware that headers that are set by Prometheus itself can't be overwritten.\n\n                        It requires Prometheus >= v2.25.0 or Thanos >= v0.24.0.\n                      type: object\n                    messageVersion:\n                      description: |-\n                        The Remote Write message's version to use when writing to the endpoint.\n\n                        `Version1.0` corresponds to the `prometheus.WriteRequest` protobuf message introduced in Remote Write 1.0.\n                        `Version2.0` corresponds to the `io.prometheus.write.v2.Request` protobuf message introduced in Remote Write 2.0.\n\n                        When `Version2.0` is selected, Prometheus will automatically be\n                        configured to append the metadata of scraped metrics to the WAL.\n\n                        Before setting this field, consult with your remote storage provider\n                        what message version it supports.\n\n                        It requires Prometheus >= v2.54.0 or Thanos >= v0.37.0.\n                      enum:\n                      - V1.0\n                      - V2.0\n                      type: string\n                    metadataConfig:\n                      description: MetadataConfig configures the sending of series metadata to the remote storage.\n                      properties:\n                        maxSamplesPerSend:\n                          description: |-\n                            MaxSamplesPerSend is the maximum number of metadata samples per send.\n\n                            It requires Prometheus >= v2.29.0.\n                          format: int32\n                          minimum: -1\n                          type: integer\n                        send:\n                          description: Defines whether metric metadata is sent to the remote storage or not.\n                          type: boolean\n                        sendInterval:\n                          description: Defines how frequently metric metadata is sent to the remote storage.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                      type: object\n                    name:\n                      description: |-\n                        The name of the remote write queue, it must be unique if specified. The\n                        name is used in metrics and logging in order to differentiate queues.\n\n                        It requires Prometheus >= v2.15.0 or Thanos >= 0.24.0.\n                      type: string\n                    noProxy:\n                      description: |-\n                        `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                        that should be excluded from proxying. IP and domain names can\n                        contain port numbers.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: string\n                    oauth2:\n                      description: |-\n                        OAuth2 configuration for the URL.\n\n                        It requires Prometheus >= v2.27.0 or Thanos >= v0.24.0.\n\n                        Cannot be set at the same time as `sigv4`, `authorization`, `basicAuth`, or `azureAd`.\n                      properties:\n                        clientId:\n                          description: |-\n                            `clientId` specifies a key of a Secret or ConfigMap containing the\n                            OAuth2 client's ID.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        clientSecret:\n                          description: |-\n                            `clientSecret` specifies a key of a Secret containing the OAuth2\n                            client's secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        endpointParams:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            `endpointParams` configures the HTTP parameters to append to the token\n                            URL.\n                          type: object\n                        noProxy:\n                          description: |-\n                            `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names\n                            that should be excluded from proxying. IP and domain names can\n                            contain port numbers.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: string\n                        proxyConnectHeader:\n                          additionalProperties:\n                            items:\n                              description: SecretKeySelector selects a key of a Secret.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            type: array\n                          description: |-\n                            ProxyConnectHeader optionally specifies headers to send to\n                            proxies during CONNECT requests.\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        proxyFromEnvironment:\n                          description: |-\n                            Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                            It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                          type: boolean\n                        proxyUrl:\n                          description: '`proxyURL` defines the HTTP proxy server to use.'\n                          pattern: ^(http|https|socks5)://.+$\n                          type: string\n                        scopes:\n                          description: '`scopes` defines the OAuth2 scopes used for the token request.'\n                          items:\n                            type: string\n                          type: array\n                        tlsConfig:\n                          description: |-\n                            TLS configuration to use when connecting to the OAuth2 server.\n                            It requires Prometheus >= v2.43.0.\n                          properties:\n                            ca:\n                              description: Certificate authority used when verifying server certificates.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            cert:\n                              description: Client certificate to present when doing client-authentication.\n                              properties:\n                                configMap:\n                                  description: ConfigMap containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key to select.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the ConfigMap or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                secret:\n                                  description: Secret containing data to use for the targets.\n                                  properties:\n                                    key:\n                                      description: The key of the secret to select from.  Must be a valid secret key.\n                                      type: string\n                                    name:\n                                      default: \"\"\n                                      description: |-\n                                        Name of the referent.\n                                        This field is effectively required, but due to backwards compatibility is\n                                        allowed to be empty. Instances of this type with an empty value here are\n                                        almost certainly wrong.\n                                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                      type: string\n                                    optional:\n                                      description: Specify whether the Secret or its key must be defined\n                                      type: boolean\n                                  required:\n                                  - key\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                              type: object\n                            insecureSkipVerify:\n                              description: Disable target certificate validation.\n                              type: boolean\n                            keySecret:\n                              description: Secret containing the client key file for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            maxVersion:\n                              description: |-\n                                Maximum acceptable TLS version.\n\n                                It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            minVersion:\n                              description: |-\n                                Minimum acceptable TLS version.\n\n                                It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                              enum:\n                              - TLS10\n                              - TLS11\n                              - TLS12\n                              - TLS13\n                              type: string\n                            serverName:\n                              description: Used to verify the hostname for the targets.\n                              type: string\n                          type: object\n                        tokenUrl:\n                          description: '`tokenURL` configures the URL to fetch the token from.'\n                          minLength: 1\n                          type: string\n                      required:\n                      - clientId\n                      - clientSecret\n                      - tokenUrl\n                      type: object\n                    proxyConnectHeader:\n                      additionalProperties:\n                        items:\n                          description: SecretKeySelector selects a key of a Secret.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        type: array\n                      description: |-\n                        ProxyConnectHeader optionally specifies headers to send to\n                        proxies during CONNECT requests.\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    proxyFromEnvironment:\n                      description: |-\n                        Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY).\n\n                        It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0.\n                      type: boolean\n                    proxyUrl:\n                      description: '`proxyURL` defines the HTTP proxy server to use.'\n                      pattern: ^(http|https|socks5)://.+$\n                      type: string\n                    queueConfig:\n                      description: QueueConfig allows tuning of the remote write queue parameters.\n                      properties:\n                        batchSendDeadline:\n                          description: BatchSendDeadline is the maximum time a sample will wait in buffer.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                        capacity:\n                          description: |-\n                            Capacity is the number of samples to buffer per shard before we start\n                            dropping them.\n                          type: integer\n                        maxBackoff:\n                          description: MaxBackoff is the maximum retry delay.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                        maxRetries:\n                          description: MaxRetries is the maximum number of times to retry a batch on recoverable errors.\n                          type: integer\n                        maxSamplesPerSend:\n                          description: MaxSamplesPerSend is the maximum number of samples per send.\n                          type: integer\n                        maxShards:\n                          description: MaxShards is the maximum number of shards, i.e. amount of concurrency.\n                          type: integer\n                        minBackoff:\n                          description: MinBackoff is the initial retry delay. Gets doubled for every retry.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                        minShards:\n                          description: MinShards is the minimum number of shards, i.e. amount of concurrency.\n                          type: integer\n                        retryOnRateLimit:\n                          description: |-\n                            Retry upon receiving a 429 status code from the remote-write storage.\n\n                            This is an *experimental feature*, it may change in any upcoming release\n                            in a breaking way.\n                          type: boolean\n                        sampleAgeLimit:\n                          description: |-\n                            SampleAgeLimit drops samples older than the limit.\n                            It requires Prometheus >= v2.50.0 or Thanos >= v0.32.0.\n                          pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                          type: string\n                      type: object\n                    remoteTimeout:\n                      description: Timeout for requests to the remote write endpoint.\n                      pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                      type: string\n                    roundRobinDNS:\n                      description: |-\n                        When enabled:\n                            - The remote-write mechanism will resolve the hostname via DNS.\n                            - It will randomly select one of the resolved IP addresses and connect to it.\n\n                        When disabled (default behavior):\n                            - The Go standard library will handle hostname resolution.\n                            - It will attempt connections to each resolved IP address sequentially.\n\n                        Note: The connection timeout applies to the entire resolution and connection process.\n                              If disabled, the timeout is distributed across all connection attempts.\n\n                        It requires Prometheus >= v3.1.0 or Thanos >= v0.38.0.\n                      type: boolean\n                    sendExemplars:\n                      description: |-\n                        Enables sending of exemplars over remote write. Note that\n                        exemplar-storage itself must be enabled using the `spec.enableFeatures`\n                        option for exemplars to be scraped in the first place.\n\n                        It requires Prometheus >= v2.27.0 or Thanos >= v0.24.0.\n                      type: boolean\n                    sendNativeHistograms:\n                      description: |-\n                        Enables sending of native histograms, also known as sparse histograms\n                        over remote write.\n\n                        It requires Prometheus >= v2.40.0 or Thanos >= v0.30.0.\n                      type: boolean\n                    sigv4:\n                      description: |-\n                        Sigv4 allows to configures AWS's Signature Verification 4 for the URL.\n\n                        It requires Prometheus >= v2.26.0 or Thanos >= v0.24.0.\n\n                        Cannot be set at the same time as `authorization`, `basicAuth`, `oauth2`, or `azureAd`.\n                      properties:\n                        accessKey:\n                          description: |-\n                            AccessKey is the AWS API key. If not specified, the environment variable\n                            `AWS_ACCESS_KEY_ID` is used.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        profile:\n                          description: Profile is the named AWS profile used to authenticate.\n                          type: string\n                        region:\n                          description: Region is the AWS region. If blank, the region from the default credentials chain used.\n                          type: string\n                        roleArn:\n                          description: RoleArn is the named AWS profile used to authenticate.\n                          type: string\n                        secretKey:\n                          description: |-\n                            SecretKey is the AWS API secret. If not specified, the environment\n                            variable `AWS_SECRET_ACCESS_KEY` is used.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      type: object\n                    tlsConfig:\n                      description: TLS Config to use for the URL.\n                      properties:\n                        ca:\n                          description: Certificate authority used when verifying server certificates.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        caFile:\n                          description: Path to the CA cert in the Prometheus container to use for the targets.\n                          type: string\n                        cert:\n                          description: Client certificate to present when doing client-authentication.\n                          properties:\n                            configMap:\n                              description: ConfigMap containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key to select.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the ConfigMap or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                            secret:\n                              description: Secret containing data to use for the targets.\n                              properties:\n                                key:\n                                  description: The key of the secret to select from.  Must be a valid secret key.\n                                  type: string\n                                name:\n                                  default: \"\"\n                                  description: |-\n                                    Name of the referent.\n                                    This field is effectively required, but due to backwards compatibility is\n                                    allowed to be empty. Instances of this type with an empty value here are\n                                    almost certainly wrong.\n                                    More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                  type: string\n                                optional:\n                                  description: Specify whether the Secret or its key must be defined\n                                  type: boolean\n                              required:\n                              - key\n                              type: object\n                              x-kubernetes-map-type: atomic\n                          type: object\n                        certFile:\n                          description: Path to the client cert file in the Prometheus container for the targets.\n                          type: string\n                        insecureSkipVerify:\n                          description: Disable target certificate validation.\n                          type: boolean\n                        keyFile:\n                          description: Path to the client key file in the Prometheus container for the targets.\n                          type: string\n                        keySecret:\n                          description: Secret containing the client key file for the targets.\n                          properties:\n                            key:\n                              description: The key of the secret to select from.  Must be a valid secret key.\n                              type: string\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                            optional:\n                              description: Specify whether the Secret or its key must be defined\n                              type: boolean\n                          required:\n                          - key\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        maxVersion:\n                          description: |-\n                            Maximum acceptable TLS version.\n\n                            It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        minVersion:\n                          description: |-\n                            Minimum acceptable TLS version.\n\n                            It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0.\n                          enum:\n                          - TLS10\n                          - TLS11\n                          - TLS12\n                          - TLS13\n                          type: string\n                        serverName:\n                          description: Used to verify the hostname for the targets.\n                          type: string\n                      type: object\n                    url:\n                      description: The URL of the endpoint to send samples to.\n                      minLength: 1\n                      type: string\n                    writeRelabelConfigs:\n                      description: The list of remote write relabel configurations.\n                      items:\n                        description: |-\n                          RelabelConfig allows dynamic rewriting of the label set for targets, alerts,\n                          scraped samples and remote write samples.\n\n                          More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config\n                        properties:\n                          action:\n                            default: replace\n                            description: |-\n                              Action to perform based on the regex matching.\n\n                              `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0.\n                              `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0.\n\n                              Default: \"Replace\"\n                            enum:\n                            - replace\n                            - Replace\n                            - keep\n                            - Keep\n                            - drop\n                            - Drop\n                            - hashmod\n                            - HashMod\n                            - labelmap\n                            - LabelMap\n                            - labeldrop\n                            - LabelDrop\n                            - labelkeep\n                            - LabelKeep\n                            - lowercase\n                            - Lowercase\n                            - uppercase\n                            - Uppercase\n                            - keepequal\n                            - KeepEqual\n                            - dropequal\n                            - DropEqual\n                            type: string\n                          modulus:\n                            description: |-\n                              Modulus to take of the hash of the source label values.\n\n                              Only applicable when the action is `HashMod`.\n                            format: int64\n                            type: integer\n                          regex:\n                            description: Regular expression against which the extracted value is matched.\n                            type: string\n                          replacement:\n                            description: |-\n                              Replacement value against which a Replace action is performed if the\n                              regular expression matches.\n\n                              Regex capture groups are available.\n                            type: string\n                          separator:\n                            description: Separator is the string between concatenated SourceLabels.\n                            type: string\n                          sourceLabels:\n                            description: |-\n                              The source labels select values from existing labels. Their content is\n                              concatenated using the configured Separator and matched against the\n                              configured regular expression.\n                            items:\n                              description: |-\n                                LabelName is a valid Prometheus label name which may only contain ASCII\n                                letters, numbers, as well as underscores.\n                              pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$\n                              type: string\n                            type: array\n                          targetLabel:\n                            description: |-\n                              Label to which the resulting string is written in a replacement.\n\n                              It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`,\n                              `KeepEqual` and `DropEqual` actions.\n\n                              Regex capture groups are available.\n                            type: string\n                        type: object\n                      type: array\n                  required:\n                  - url\n                  type: object\n                type: array\n              replicas:\n                description: Number of thanos ruler instances to deploy.\n                format: int32\n                type: integer\n              resendDelay:\n                description: Minimum amount of time to wait before resending an alert to Alertmanager.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              resources:\n                description: |-\n                  Resources defines the resource requirements for single Pods.\n                  If not provided, no requests/limits will be set\n                properties:\n                  claims:\n                    description: |-\n                      Claims lists the names of resources, defined in spec.resourceClaims,\n                      that are used by this container.\n\n                      This is an alpha field and requires enabling the\n                      DynamicResourceAllocation feature gate.\n\n                      This field is immutable. It can only be set for containers.\n                    items:\n                      description: ResourceClaim references one entry in PodSpec.ResourceClaims.\n                      properties:\n                        name:\n                          description: |-\n                            Name must match the name of one entry in pod.spec.resourceClaims of\n                            the Pod where this field is used. It makes that resource available\n                            inside a container.\n                          type: string\n                        request:\n                          description: |-\n                            Request is the name chosen for a request in the referenced claim.\n                            If empty, everything from the claim is made available, otherwise\n                            only the result of this request.\n                          type: string\n                      required:\n                      - name\n                      type: object\n                    type: array\n                    x-kubernetes-list-map-keys:\n                    - name\n                    x-kubernetes-list-type: map\n                  limits:\n                    additionalProperties:\n                      anyOf:\n                      - type: integer\n                      - type: string\n                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                      x-kubernetes-int-or-string: true\n                    description: |-\n                      Limits describes the maximum amount of compute resources allowed.\n                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                    type: object\n                  requests:\n                    additionalProperties:\n                      anyOf:\n                      - type: integer\n                      - type: string\n                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                      x-kubernetes-int-or-string: true\n                    description: |-\n                      Requests describes the minimum amount of compute resources required.\n                      If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                      otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                    type: object\n                type: object\n              retention:\n                default: 24h\n                description: |-\n                  Time duration ThanosRuler shall retain data for. Default is '24h', and\n                  must match the regular expression `[0-9]+(ms|s|m|h|d|w|y)` (milliseconds\n                  seconds minutes hours days weeks years).\n\n                  The field has no effect when remote-write is configured since the Ruler\n                  operates in stateless mode.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              routePrefix:\n                description: The route prefix ThanosRuler registers HTTP handlers for. This allows thanos UI to be served on a sub-path.\n                type: string\n              ruleConcurrentEval:\n                description: |-\n                  How many rules can be evaluated concurrently.\n                  It requires Thanos >= v0.37.0.\n                format: int32\n                minimum: 1\n                type: integer\n              ruleGracePeriod:\n                description: |-\n                  Minimum duration between alert and restored \"for\" state.\n                  This is maintained only for alerts with configured \"for\" time greater than grace period.\n                  It requires Thanos >= v0.30.0.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              ruleNamespaceSelector:\n                description: |-\n                  Namespaces to be selected for Rules discovery. If unspecified, only\n                  the same namespace as the ThanosRuler object is in is used.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              ruleOutageTolerance:\n                description: |-\n                  Max time to tolerate prometheus outage for restoring \"for\" state of alert.\n                  It requires Thanos >= v0.30.0.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              ruleQueryOffset:\n                description: |-\n                  The default rule group's query offset duration to use.\n                  It requires Thanos >= v0.38.0.\n                pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$\n                type: string\n              ruleSelector:\n                description: |-\n                  PrometheusRule objects to be selected for rule evaluation. An empty\n                  label selector matches all objects. A null label selector matches no\n                  objects.\n                properties:\n                  matchExpressions:\n                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                    items:\n                      description: |-\n                        A label selector requirement is a selector that contains values, a key, and an operator that\n                        relates the key and values.\n                      properties:\n                        key:\n                          description: key is the label key that the selector applies to.\n                          type: string\n                        operator:\n                          description: |-\n                            operator represents a key's relationship to a set of values.\n                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                          type: string\n                        values:\n                          description: |-\n                            values is an array of string values. If the operator is In or NotIn,\n                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                            the values array must be empty. This array is replaced during a strategic\n                            merge patch.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      required:\n                      - key\n                      - operator\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  matchLabels:\n                    additionalProperties:\n                      type: string\n                    description: |-\n                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                    type: object\n                type: object\n                x-kubernetes-map-type: atomic\n              securityContext:\n                description: |-\n                  SecurityContext holds pod-level security attributes and common container settings.\n                  This defaults to the default PodSecurityContext.\n                properties:\n                  appArmorProfile:\n                    description: |-\n                      appArmorProfile is the AppArmor options to use by the containers in this pod.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    properties:\n                      localhostProfile:\n                        description: |-\n                          localhostProfile indicates a profile loaded on the node that should be used.\n                          The profile must be preconfigured on the node to work.\n                          Must match the loaded name of the profile.\n                          Must be set if and only if type is \"Localhost\".\n                        type: string\n                      type:\n                        description: |-\n                          type indicates which kind of AppArmor profile will be applied.\n                          Valid options are:\n                            Localhost - a profile pre-loaded on the node.\n                            RuntimeDefault - the container runtime's default profile.\n                            Unconfined - no AppArmor enforcement.\n                        type: string\n                    required:\n                    - type\n                    type: object\n                  fsGroup:\n                    description: |-\n                      A special supplemental group that applies to all containers in a pod.\n                      Some volume types allow the Kubelet to change the ownership of that volume\n                      to be owned by the pod:\n\n                      1. The owning GID will be the FSGroup\n                      2. The setgid bit is set (new files created in the volume will be owned by FSGroup)\n                      3. The permission bits are OR'd with rw-rw----\n\n                      If unset, the Kubelet will not modify the ownership and permissions of any volume.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    format: int64\n                    type: integer\n                  fsGroupChangePolicy:\n                    description: |-\n                      fsGroupChangePolicy defines behavior of changing ownership and permission of the volume\n                      before being exposed inside Pod. This field will only apply to\n                      volume types which support fsGroup based ownership(and permissions).\n                      It will have no effect on ephemeral volume types such as: secret, configmaps\n                      and emptydir.\n                      Valid values are \"OnRootMismatch\" and \"Always\". If not specified, \"Always\" is used.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    type: string\n                  runAsGroup:\n                    description: |-\n                      The GID to run the entrypoint of the container process.\n                      Uses runtime default if unset.\n                      May also be set in SecurityContext.  If set in both SecurityContext and\n                      PodSecurityContext, the value specified in SecurityContext takes precedence\n                      for that container.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    format: int64\n                    type: integer\n                  runAsNonRoot:\n                    description: |-\n                      Indicates that the container must run as a non-root user.\n                      If true, the Kubelet will validate the image at runtime to ensure that it\n                      does not run as UID 0 (root) and fail to start the container if it does.\n                      If unset or false, no such validation will be performed.\n                      May also be set in SecurityContext.  If set in both SecurityContext and\n                      PodSecurityContext, the value specified in SecurityContext takes precedence.\n                    type: boolean\n                  runAsUser:\n                    description: |-\n                      The UID to run the entrypoint of the container process.\n                      Defaults to user specified in image metadata if unspecified.\n                      May also be set in SecurityContext.  If set in both SecurityContext and\n                      PodSecurityContext, the value specified in SecurityContext takes precedence\n                      for that container.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    format: int64\n                    type: integer\n                  seLinuxChangePolicy:\n                    description: |-\n                      seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod.\n                      It has no effect on nodes that do not support SELinux or to volumes does not support SELinux.\n                      Valid values are \"MountOption\" and \"Recursive\".\n\n                      \"Recursive\" means relabeling of all files on all Pod volumes by the container runtime.\n                      This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node.\n\n                      \"MountOption\" mounts all eligible Pod volumes with `-o context` mount option.\n                      This requires all Pods that share the same volume to use the same SELinux label.\n                      It is not possible to share the same volume among privileged and unprivileged Pods.\n                      Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes\n                      whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their\n                      CSIDriver instance. Other volumes are always re-labelled recursively.\n                      \"MountOption\" value is allowed only when SELinuxMount feature gate is enabled.\n\n                      If not specified and SELinuxMount feature gate is enabled, \"MountOption\" is used.\n                      If not specified and SELinuxMount feature gate is disabled, \"MountOption\" is used for ReadWriteOncePod volumes\n                      and \"Recursive\" for all other volumes.\n\n                      This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers.\n\n                      All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    type: string\n                  seLinuxOptions:\n                    description: |-\n                      The SELinux context to be applied to all containers.\n                      If unspecified, the container runtime will allocate a random SELinux context for each\n                      container.  May also be set in SecurityContext.  If set in\n                      both SecurityContext and PodSecurityContext, the value specified in SecurityContext\n                      takes precedence for that container.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    properties:\n                      level:\n                        description: Level is SELinux level label that applies to the container.\n                        type: string\n                      role:\n                        description: Role is a SELinux role label that applies to the container.\n                        type: string\n                      type:\n                        description: Type is a SELinux type label that applies to the container.\n                        type: string\n                      user:\n                        description: User is a SELinux user label that applies to the container.\n                        type: string\n                    type: object\n                  seccompProfile:\n                    description: |-\n                      The seccomp options to use by the containers in this pod.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    properties:\n                      localhostProfile:\n                        description: |-\n                          localhostProfile indicates a profile defined in a file on the node should be used.\n                          The profile must be preconfigured on the node to work.\n                          Must be a descending path, relative to the kubelet's configured seccomp profile location.\n                          Must be set if type is \"Localhost\". Must NOT be set for any other type.\n                        type: string\n                      type:\n                        description: |-\n                          type indicates which kind of seccomp profile will be applied.\n                          Valid options are:\n\n                          Localhost - a profile defined in a file on the node should be used.\n                          RuntimeDefault - the container runtime default profile should be used.\n                          Unconfined - no profile should be applied.\n                        type: string\n                    required:\n                    - type\n                    type: object\n                  supplementalGroups:\n                    description: |-\n                      A list of groups applied to the first process run in each container, in\n                      addition to the container's primary GID and fsGroup (if specified).  If\n                      the SupplementalGroupsPolicy feature is enabled, the\n                      supplementalGroupsPolicy field determines whether these are in addition\n                      to or instead of any group memberships defined in the container image.\n                      If unspecified, no additional groups are added, though group memberships\n                      defined in the container image may still be used, depending on the\n                      supplementalGroupsPolicy field.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    items:\n                      format: int64\n                      type: integer\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  supplementalGroupsPolicy:\n                    description: |-\n                      Defines how supplemental groups of the first container processes are calculated.\n                      Valid values are \"Merge\" and \"Strict\". If not specified, \"Merge\" is used.\n                      (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled\n                      and the container runtime must implement support for this feature.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    type: string\n                  sysctls:\n                    description: |-\n                      Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported\n                      sysctls (by the container runtime) might fail to launch.\n                      Note that this field cannot be set when spec.os.name is windows.\n                    items:\n                      description: Sysctl defines a kernel parameter to be set\n                      properties:\n                        name:\n                          description: Name of a property to set\n                          type: string\n                        value:\n                          description: Value of a property to set\n                          type: string\n                      required:\n                      - name\n                      - value\n                      type: object\n                    type: array\n                    x-kubernetes-list-type: atomic\n                  windowsOptions:\n                    description: |-\n                      The Windows specific settings applied to all containers.\n                      If unspecified, the options within a container's SecurityContext will be used.\n                      If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.\n                      Note that this field cannot be set when spec.os.name is linux.\n                    properties:\n                      gmsaCredentialSpec:\n                        description: |-\n                          GMSACredentialSpec is where the GMSA admission webhook\n                          (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the\n                          GMSA credential spec named by the GMSACredentialSpecName field.\n                        type: string\n                      gmsaCredentialSpecName:\n                        description: GMSACredentialSpecName is the name of the GMSA credential spec to use.\n                        type: string\n                      hostProcess:\n                        description: |-\n                          HostProcess determines if a container should be run as a 'Host Process' container.\n                          All of a Pod's containers must have the same effective HostProcess value\n                          (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).\n                          In addition, if HostProcess is true then HostNetwork must also be set to true.\n                        type: boolean\n                      runAsUserName:\n                        description: |-\n                          The UserName in Windows to run the entrypoint of the container process.\n                          Defaults to the user specified in image metadata if unspecified.\n                          May also be set in PodSecurityContext. If set in both SecurityContext and\n                          PodSecurityContext, the value specified in SecurityContext takes precedence.\n                        type: string\n                    type: object\n                type: object\n              serviceAccountName:\n                description: |-\n                  ServiceAccountName is the name of the ServiceAccount to use to run the\n                  Thanos Ruler Pods.\n                type: string\n              serviceName:\n                description: |-\n                  The name of the service name used by the underlying StatefulSet(s) as the governing service.\n                  If defined, the Service  must be created before the ThanosRuler resource in the same namespace and it must define a selector that matches the pod labels.\n                  If empty, the operator will create and manage a headless service named `thanos-ruler-operated` for ThanosRuler resources.\n                  When deploying multiple ThanosRuler resources in the same namespace, it is recommended to specify a different value for each.\n                  See https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id for more details.\n                minLength: 1\n                type: string\n              storage:\n                description: Storage spec to specify how storage shall be used.\n                properties:\n                  disableMountSubPath:\n                    description: 'Deprecated: subPath usage will be removed in a future release.'\n                    type: boolean\n                  emptyDir:\n                    description: |-\n                      EmptyDirVolumeSource to be used by the StatefulSet.\n                      If specified, it takes precedence over `ephemeral` and `volumeClaimTemplate`.\n                      More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir\n                    properties:\n                      medium:\n                        description: |-\n                          medium represents what type of storage medium should back this directory.\n                          The default is \"\" which means to use the node's default medium.\n                          Must be an empty string (default) or Memory.\n                          More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                        type: string\n                      sizeLimit:\n                        anyOf:\n                        - type: integer\n                        - type: string\n                        description: |-\n                          sizeLimit is the total amount of local storage required for this EmptyDir volume.\n                          The size limit is also applicable for memory medium.\n                          The maximum usage on memory medium EmptyDir would be the minimum value between\n                          the SizeLimit specified here and the sum of memory limits of all containers in a pod.\n                          The default is nil which means that the limit is undefined.\n                          More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                        pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                        x-kubernetes-int-or-string: true\n                    type: object\n                  ephemeral:\n                    description: |-\n                      EphemeralVolumeSource to be used by the StatefulSet.\n                      This is a beta field in k8s 1.21 and GA in 1.15.\n                      For lower versions, starting with k8s 1.19, it requires enabling the GenericEphemeralVolume feature gate.\n                      More info: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes\n                    properties:\n                      volumeClaimTemplate:\n                        description: |-\n                          Will be used to create a stand-alone PVC to provision the volume.\n                          The pod in which this EphemeralVolumeSource is embedded will be the\n                          owner of the PVC, i.e. the PVC will be deleted together with the\n                          pod.  The name of the PVC will be `<pod name>-<volume name>` where\n                          `<volume name>` is the name from the `PodSpec.Volumes` array\n                          entry. Pod validation will reject the pod if the concatenated name\n                          is not valid for a PVC (for example, too long).\n\n                          An existing PVC with that name that is not owned by the pod\n                          will *not* be used for the pod to avoid using an unrelated\n                          volume by mistake. Starting the pod is then blocked until\n                          the unrelated PVC is removed. If such a pre-created PVC is\n                          meant to be used by the pod, the PVC has to updated with an\n                          owner reference to the pod once the pod exists. Normally\n                          this should not be necessary, but it may be useful when\n                          manually reconstructing a broken cluster.\n\n                          This field is read-only and no changes will be made by Kubernetes\n                          to the PVC after it has been created.\n\n                          Required, must not be nil.\n                        properties:\n                          metadata:\n                            description: |-\n                              May contain labels and annotations that will be copied into the PVC\n                              when creating it. No other fields are allowed and will be rejected during\n                              validation.\n                            type: object\n                          spec:\n                            description: |-\n                              The specification for the PersistentVolumeClaim. The entire content is\n                              copied unchanged into the PVC that gets created from this\n                              template. The same fields as in a PersistentVolumeClaim\n                              are also valid here.\n                            properties:\n                              accessModes:\n                                description: |-\n                                  accessModes contains the desired access modes the volume should have.\n                                  More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                                items:\n                                  type: string\n                                type: array\n                                x-kubernetes-list-type: atomic\n                              dataSource:\n                                description: |-\n                                  dataSource field can be used to specify either:\n                                  * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n                                  * An existing PVC (PersistentVolumeClaim)\n                                  If the provisioner or an external controller can support the specified data source,\n                                  it will create a new volume based on the contents of the specified data source.\n                                  When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\n                                  and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\n                                  If the namespace is specified, then dataSourceRef will not be copied to dataSource.\n                                properties:\n                                  apiGroup:\n                                    description: |-\n                                      APIGroup is the group for the resource being referenced.\n                                      If APIGroup is not specified, the specified Kind must be in the core API group.\n                                      For any other third-party types, APIGroup is required.\n                                    type: string\n                                  kind:\n                                    description: Kind is the type of resource being referenced\n                                    type: string\n                                  name:\n                                    description: Name is the name of resource being referenced\n                                    type: string\n                                required:\n                                - kind\n                                - name\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              dataSourceRef:\n                                description: |-\n                                  dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\n                                  volume is desired. This may be any object from a non-empty API group (non\n                                  core object) or a PersistentVolumeClaim object.\n                                  When this field is specified, volume binding will only succeed if the type of\n                                  the specified object matches some installed volume populator or dynamic\n                                  provisioner.\n                                  This field will replace the functionality of the dataSource field and as such\n                                  if both fields are non-empty, they must have the same value. For backwards\n                                  compatibility, when namespace isn't specified in dataSourceRef,\n                                  both fields (dataSource and dataSourceRef) will be set to the same\n                                  value automatically if one of them is empty and the other is non-empty.\n                                  When namespace is specified in dataSourceRef,\n                                  dataSource isn't set to the same value and must be empty.\n                                  There are three important differences between dataSource and dataSourceRef:\n                                  * While dataSource only allows two specific types of objects, dataSourceRef\n                                    allows any non-core object, as well as PersistentVolumeClaim objects.\n                                  * While dataSource ignores disallowed values (dropping them), dataSourceRef\n                                    preserves all values, and generates an error if a disallowed value is\n                                    specified.\n                                  * While dataSource only allows local objects, dataSourceRef allows objects\n                                    in any namespaces.\n                                  (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n                                  (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                properties:\n                                  apiGroup:\n                                    description: |-\n                                      APIGroup is the group for the resource being referenced.\n                                      If APIGroup is not specified, the specified Kind must be in the core API group.\n                                      For any other third-party types, APIGroup is required.\n                                    type: string\n                                  kind:\n                                    description: Kind is the type of resource being referenced\n                                    type: string\n                                  name:\n                                    description: Name is the name of resource being referenced\n                                    type: string\n                                  namespace:\n                                    description: |-\n                                      Namespace is the namespace of resource being referenced\n                                      Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n                                      (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                    type: string\n                                required:\n                                - kind\n                                - name\n                                type: object\n                              resources:\n                                description: |-\n                                  resources represents the minimum resources the volume should have.\n                                  If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\n                                  that are lower than previous value but must still be higher than capacity recorded in the\n                                  status field of the claim.\n                                  More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources\n                                properties:\n                                  limits:\n                                    additionalProperties:\n                                      anyOf:\n                                      - type: integer\n                                      - type: string\n                                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                      x-kubernetes-int-or-string: true\n                                    description: |-\n                                      Limits describes the maximum amount of compute resources allowed.\n                                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                    type: object\n                                  requests:\n                                    additionalProperties:\n                                      anyOf:\n                                      - type: integer\n                                      - type: string\n                                      pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                      x-kubernetes-int-or-string: true\n                                    description: |-\n                                      Requests describes the minimum amount of compute resources required.\n                                      If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                                      otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                                      More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                    type: object\n                                type: object\n                              selector:\n                                description: selector is a label query over volumes to consider for binding.\n                                properties:\n                                  matchExpressions:\n                                    description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                    items:\n                                      description: |-\n                                        A label selector requirement is a selector that contains values, a key, and an operator that\n                                        relates the key and values.\n                                      properties:\n                                        key:\n                                          description: key is the label key that the selector applies to.\n                                          type: string\n                                        operator:\n                                          description: |-\n                                            operator represents a key's relationship to a set of values.\n                                            Valid operators are In, NotIn, Exists and DoesNotExist.\n                                          type: string\n                                        values:\n                                          description: |-\n                                            values is an array of string values. If the operator is In or NotIn,\n                                            the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                            the values array must be empty. This array is replaced during a strategic\n                                            merge patch.\n                                          items:\n                                            type: string\n                                          type: array\n                                          x-kubernetes-list-type: atomic\n                                      required:\n                                      - key\n                                      - operator\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                  matchLabels:\n                                    additionalProperties:\n                                      type: string\n                                    description: |-\n                                      matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                      map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                      operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                    type: object\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              storageClassName:\n                                description: |-\n                                  storageClassName is the name of the StorageClass required by the claim.\n                                  More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1\n                                type: string\n                              volumeAttributesClassName:\n                                description: |-\n                                  volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\n                                  If specified, the CSI driver will create or update the volume with the attributes defined\n                                  in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\n                                  it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\n                                  will be applied to the claim but it's not allowed to reset this field to empty string once it is set.\n                                  If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\n                                  will be set by the persistentvolume controller if it exists.\n                                  If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\n                                  set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\n                                  exists.\n                                  More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n                                  (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).\n                                type: string\n                              volumeMode:\n                                description: |-\n                                  volumeMode defines what type of volume is required by the claim.\n                                  Value of Filesystem is implied when not included in claim spec.\n                                type: string\n                              volumeName:\n                                description: volumeName is the binding reference to the PersistentVolume backing this claim.\n                                type: string\n                            type: object\n                        required:\n                        - spec\n                        type: object\n                    type: object\n                  volumeClaimTemplate:\n                    description: |-\n                      Defines the PVC spec to be used by the Prometheus StatefulSets.\n                      The easiest way to use a volume that cannot be automatically provisioned\n                      is to use a label selector alongside manually created PersistentVolumes.\n                    properties:\n                      apiVersion:\n                        description: |-\n                          APIVersion defines the versioned schema of this representation of an object.\n                          Servers should convert recognized schemas to the latest internal value, and\n                          may reject unrecognized values.\n                          More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n                        type: string\n                      kind:\n                        description: |-\n                          Kind is a string value representing the REST resource this object represents.\n                          Servers may infer this from the endpoint the client submits requests to.\n                          Cannot be updated.\n                          In CamelCase.\n                          More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n                        type: string\n                      metadata:\n                        description: EmbeddedMetadata contains metadata relevant to an EmbeddedResource.\n                        properties:\n                          annotations:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              Annotations is an unstructured key value map stored with a resource that may be\n                              set by external tools to store and retrieve arbitrary metadata. They are not\n                              queryable and should be preserved when modifying objects.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/\n                            type: object\n                          labels:\n                            additionalProperties:\n                              type: string\n                            description: |-\n                              Map of string keys and values that can be used to organize and categorize\n                              (scope and select) objects. May match selectors of replication controllers\n                              and services.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/\n                            type: object\n                          name:\n                            description: |-\n                              Name must be unique within a namespace. Is required when creating resources, although\n                              some resources may allow a client to request the generation of an appropriate name\n                              automatically. Name is primarily intended for creation idempotence and configuration\n                              definition.\n                              Cannot be updated.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/\n                            type: string\n                        type: object\n                      spec:\n                        description: |-\n                          Defines the desired characteristics of a volume requested by a pod author.\n                          More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims\n                        properties:\n                          accessModes:\n                            description: |-\n                              accessModes contains the desired access modes the volume should have.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                            items:\n                              type: string\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          dataSource:\n                            description: |-\n                              dataSource field can be used to specify either:\n                              * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n                              * An existing PVC (PersistentVolumeClaim)\n                              If the provisioner or an external controller can support the specified data source,\n                              it will create a new volume based on the contents of the specified data source.\n                              When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\n                              and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\n                              If the namespace is specified, then dataSourceRef will not be copied to dataSource.\n                            properties:\n                              apiGroup:\n                                description: |-\n                                  APIGroup is the group for the resource being referenced.\n                                  If APIGroup is not specified, the specified Kind must be in the core API group.\n                                  For any other third-party types, APIGroup is required.\n                                type: string\n                              kind:\n                                description: Kind is the type of resource being referenced\n                                type: string\n                              name:\n                                description: Name is the name of resource being referenced\n                                type: string\n                            required:\n                            - kind\n                            - name\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          dataSourceRef:\n                            description: |-\n                              dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\n                              volume is desired. This may be any object from a non-empty API group (non\n                              core object) or a PersistentVolumeClaim object.\n                              When this field is specified, volume binding will only succeed if the type of\n                              the specified object matches some installed volume populator or dynamic\n                              provisioner.\n                              This field will replace the functionality of the dataSource field and as such\n                              if both fields are non-empty, they must have the same value. For backwards\n                              compatibility, when namespace isn't specified in dataSourceRef,\n                              both fields (dataSource and dataSourceRef) will be set to the same\n                              value automatically if one of them is empty and the other is non-empty.\n                              When namespace is specified in dataSourceRef,\n                              dataSource isn't set to the same value and must be empty.\n                              There are three important differences between dataSource and dataSourceRef:\n                              * While dataSource only allows two specific types of objects, dataSourceRef\n                                allows any non-core object, as well as PersistentVolumeClaim objects.\n                              * While dataSource ignores disallowed values (dropping them), dataSourceRef\n                                preserves all values, and generates an error if a disallowed value is\n                                specified.\n                              * While dataSource only allows local objects, dataSourceRef allows objects\n                                in any namespaces.\n                              (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n                              (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                            properties:\n                              apiGroup:\n                                description: |-\n                                  APIGroup is the group for the resource being referenced.\n                                  If APIGroup is not specified, the specified Kind must be in the core API group.\n                                  For any other third-party types, APIGroup is required.\n                                type: string\n                              kind:\n                                description: Kind is the type of resource being referenced\n                                type: string\n                              name:\n                                description: Name is the name of resource being referenced\n                                type: string\n                              namespace:\n                                description: |-\n                                  Namespace is the namespace of resource being referenced\n                                  Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n                                  (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                type: string\n                            required:\n                            - kind\n                            - name\n                            type: object\n                          resources:\n                            description: |-\n                              resources represents the minimum resources the volume should have.\n                              If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\n                              that are lower than previous value but must still be higher than capacity recorded in the\n                              status field of the claim.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources\n                            properties:\n                              limits:\n                                additionalProperties:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                  x-kubernetes-int-or-string: true\n                                description: |-\n                                  Limits describes the maximum amount of compute resources allowed.\n                                  More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                type: object\n                              requests:\n                                additionalProperties:\n                                  anyOf:\n                                  - type: integer\n                                  - type: string\n                                  pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                  x-kubernetes-int-or-string: true\n                                description: |-\n                                  Requests describes the minimum amount of compute resources required.\n                                  If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                                  otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                                  More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                type: object\n                            type: object\n                          selector:\n                            description: selector is a label query over volumes to consider for binding.\n                            properties:\n                              matchExpressions:\n                                description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                items:\n                                  description: |-\n                                    A label selector requirement is a selector that contains values, a key, and an operator that\n                                    relates the key and values.\n                                  properties:\n                                    key:\n                                      description: key is the label key that the selector applies to.\n                                      type: string\n                                    operator:\n                                      description: |-\n                                        operator represents a key's relationship to a set of values.\n                                        Valid operators are In, NotIn, Exists and DoesNotExist.\n                                      type: string\n                                    values:\n                                      description: |-\n                                        values is an array of string values. If the operator is In or NotIn,\n                                        the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                        the values array must be empty. This array is replaced during a strategic\n                                        merge patch.\n                                      items:\n                                        type: string\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                  required:\n                                  - key\n                                  - operator\n                                  type: object\n                                type: array\n                                x-kubernetes-list-type: atomic\n                              matchLabels:\n                                additionalProperties:\n                                  type: string\n                                description: |-\n                                  matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                  map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                  operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                type: object\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          storageClassName:\n                            description: |-\n                              storageClassName is the name of the StorageClass required by the claim.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1\n                            type: string\n                          volumeAttributesClassName:\n                            description: |-\n                              volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\n                              If specified, the CSI driver will create or update the volume with the attributes defined\n                              in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\n                              it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\n                              will be applied to the claim but it's not allowed to reset this field to empty string once it is set.\n                              If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\n                              will be set by the persistentvolume controller if it exists.\n                              If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\n                              set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\n                              exists.\n                              More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n                              (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).\n                            type: string\n                          volumeMode:\n                            description: |-\n                              volumeMode defines what type of volume is required by the claim.\n                              Value of Filesystem is implied when not included in claim spec.\n                            type: string\n                          volumeName:\n                            description: volumeName is the binding reference to the PersistentVolume backing this claim.\n                            type: string\n                        type: object\n                      status:\n                        description: 'Deprecated: this field is never set.'\n                        properties:\n                          accessModes:\n                            description: |-\n                              accessModes contains the actual access modes the volume backing the PVC has.\n                              More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                            items:\n                              type: string\n                            type: array\n                            x-kubernetes-list-type: atomic\n                          allocatedResourceStatuses:\n                            additionalProperties:\n                              description: |-\n                                When a controller receives persistentvolume claim update with ClaimResourceStatus for a resource\n                                that it does not recognizes, then it should ignore that update and let other controllers\n                                handle it.\n                              type: string\n                            description: \"allocatedResourceStatuses stores status of resource being resized for the given PVC.\\nKey names follow standard Kubernetes label syntax. Valid values are either:\\n\\t* Un-prefixed keys:\\n\\t\\t- storage - the capacity of the volume.\\n\\t* Custom resources must use implementation-defined prefixed names such as \\\"example.com/my-custom-resource\\\"\\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\\nreserved and hence may not be used.\\n\\nClaimResourceStatus can be in any of following states:\\n\\t- ControllerResizeInProgress:\\n\\t\\tState set when resize controller starts resizing the volume in control-plane.\\n\\t- ControllerResizeFailed:\\n\\t\\tState set when resize has failed in resize controller with a terminal error.\\n\\t- NodeResizePending:\\n\\t\\tState set when resize controller has finished resizing the volume but further resizing of\\n\\t\\tvolume is needed on the node.\\n\\t- NodeResizeInProgress:\\n\\t\\tState set when kubelet starts resizing the volume.\\n\\t- NodeResizeFailed:\\n\\t\\tState set when resizing has failed in kubelet with a terminal error. Transient errors don't set\\n\\t\\tNodeResizeFailed.\\nFor example: if expanding a PVC for more capacity - this field can be one of the following states:\\n\\t- pvc.status.allocatedResourceStatus['storage'] = \\\"ControllerResizeInProgress\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"ControllerResizeFailed\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"NodeResizePending\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"NodeResizeInProgress\\\"\\n     - pvc.status.allocatedResourceStatus['storage'] = \\\"NodeResizeFailed\\\"\\nWhen this field is not set, it means that no resize operation is in progress for the given PVC.\\n\\nA controller that receives PVC update with previously unknown resourceName or ClaimResourceStatus\\nshould ignore the update for the purpose it was designed. For example - a controller that\\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\\nresources associated with PVC.\\n\\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.\"\n                            type: object\n                            x-kubernetes-map-type: granular\n                          allocatedResources:\n                            additionalProperties:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                              x-kubernetes-int-or-string: true\n                            description: \"allocatedResources tracks the resources allocated to a PVC including its capacity.\\nKey names follow standard Kubernetes label syntax. Valid values are either:\\n\\t* Un-prefixed keys:\\n\\t\\t- storage - the capacity of the volume.\\n\\t* Custom resources must use implementation-defined prefixed names such as \\\"example.com/my-custom-resource\\\"\\nApart from above values - keys that are unprefixed or have kubernetes.io prefix are considered\\nreserved and hence may not be used.\\n\\nCapacity reported here may be larger than the actual capacity when a volume expansion operation\\nis requested.\\nFor storage quota, the larger value from allocatedResources and PVC.spec.resources is used.\\nIf allocatedResources is not set, PVC.spec.resources alone is used for quota calculation.\\nIf a volume expansion capacity request is lowered, allocatedResources is only\\nlowered if there are no expansion operations in progress and if the actual volume capacity\\nis equal or lower than the requested capacity.\\n\\nA controller that receives PVC update with previously unknown resourceName\\nshould ignore the update for the purpose it was designed. For example - a controller that\\nonly is responsible for resizing capacity of the volume, should ignore PVC updates that change other valid\\nresources associated with PVC.\\n\\nThis is an alpha field and requires enabling RecoverVolumeExpansionFailure feature.\"\n                            type: object\n                          capacity:\n                            additionalProperties:\n                              anyOf:\n                              - type: integer\n                              - type: string\n                              pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                              x-kubernetes-int-or-string: true\n                            description: capacity represents the actual resources of the underlying volume.\n                            type: object\n                          conditions:\n                            description: |-\n                              conditions is the current Condition of persistent volume claim. If underlying persistent volume is being\n                              resized then the Condition will be set to 'Resizing'.\n                            items:\n                              description: PersistentVolumeClaimCondition contains details about state of pvc\n                              properties:\n                                lastProbeTime:\n                                  description: lastProbeTime is the time we probed the condition.\n                                  format: date-time\n                                  type: string\n                                lastTransitionTime:\n                                  description: lastTransitionTime is the time the condition transitioned from one status to another.\n                                  format: date-time\n                                  type: string\n                                message:\n                                  description: message is the human-readable message indicating details about last transition.\n                                  type: string\n                                reason:\n                                  description: |-\n                                    reason is a unique, this should be a short, machine understandable string that gives the reason\n                                    for condition's last transition. If it reports \"Resizing\" that means the underlying\n                                    persistent volume is being resized.\n                                  type: string\n                                status:\n                                  description: |-\n                                    Status is the status of the condition.\n                                    Can be True, False, Unknown.\n                                    More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=state%20of%20pvc-,conditions.status,-(string)%2C%20required\n                                  type: string\n                                type:\n                                  description: |-\n                                    Type is the type of the condition.\n                                    More info: https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#:~:text=set%20to%20%27ResizeStarted%27.-,PersistentVolumeClaimCondition,-contains%20details%20about\n                                  type: string\n                              required:\n                              - status\n                              - type\n                              type: object\n                            type: array\n                            x-kubernetes-list-map-keys:\n                            - type\n                            x-kubernetes-list-type: map\n                          currentVolumeAttributesClassName:\n                            description: |-\n                              currentVolumeAttributesClassName is the current name of the VolumeAttributesClass the PVC is using.\n                              When unset, there is no VolumeAttributeClass applied to this PersistentVolumeClaim\n                              This is a beta field and requires enabling VolumeAttributesClass feature (off by default).\n                            type: string\n                          modifyVolumeStatus:\n                            description: |-\n                              ModifyVolumeStatus represents the status object of ControllerModifyVolume operation.\n                              When this is unset, there is no ModifyVolume operation being attempted.\n                              This is a beta field and requires enabling VolumeAttributesClass feature (off by default).\n                            properties:\n                              status:\n                                description: \"status is the status of the ControllerModifyVolume operation. It can be in any of following states:\\n - Pending\\n   Pending indicates that the PersistentVolumeClaim cannot be modified due to unmet requirements, such as\\n   the specified VolumeAttributesClass not existing.\\n - InProgress\\n   InProgress indicates that the volume is being modified.\\n - Infeasible\\n  Infeasible indicates that the request has been rejected as invalid by the CSI driver. To\\n\\t  resolve the error, a valid VolumeAttributesClass needs to be specified.\\nNote: New statuses can be added in the future. Consumers should check for unknown statuses and fail appropriately.\"\n                                type: string\n                              targetVolumeAttributesClassName:\n                                description: targetVolumeAttributesClassName is the name of the VolumeAttributesClass the PVC currently being reconciled\n                                type: string\n                            required:\n                            - status\n                            type: object\n                          phase:\n                            description: phase represents the current phase of PersistentVolumeClaim.\n                            type: string\n                        type: object\n                    type: object\n                type: object\n              terminationGracePeriodSeconds:\n                description: |-\n                  Optional duration in seconds the pod needs to terminate gracefully.\n                  Value must be non-negative integer. The value zero indicates stop immediately via\n                  the kill signal (no opportunity to shut down) which may lead to data corruption.\n\n                  Defaults to 120 seconds.\n                format: int64\n                minimum: 0\n                type: integer\n              tolerations:\n                description: If specified, the pod's tolerations.\n                items:\n                  description: |-\n                    The pod this Toleration is attached to tolerates any taint that matches\n                    the triple <key,value,effect> using the matching operator <operator>.\n                  properties:\n                    effect:\n                      description: |-\n                        Effect indicates the taint effect to match. Empty means match all taint effects.\n                        When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.\n                      type: string\n                    key:\n                      description: |-\n                        Key is the taint key that the toleration applies to. Empty means match all taint keys.\n                        If the key is empty, operator must be Exists; this combination means to match all values and all keys.\n                      type: string\n                    operator:\n                      description: |-\n                        Operator represents a key's relationship to the value.\n                        Valid operators are Exists and Equal. Defaults to Equal.\n                        Exists is equivalent to wildcard for value, so that a pod can\n                        tolerate all taints of a particular category.\n                      type: string\n                    tolerationSeconds:\n                      description: |-\n                        TolerationSeconds represents the period of time the toleration (which must be\n                        of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,\n                        it is not set, which means tolerate the taint forever (do not evict). Zero and\n                        negative values will be treated as 0 (evict immediately) by the system.\n                      format: int64\n                      type: integer\n                    value:\n                      description: |-\n                        Value is the taint value the toleration matches to.\n                        If the operator is Exists, the value should be empty, otherwise just a regular string.\n                      type: string\n                  type: object\n                type: array\n              topologySpreadConstraints:\n                description: If specified, the pod's topology spread constraints.\n                items:\n                  description: TopologySpreadConstraint specifies how to spread matching pods among the given topology.\n                  properties:\n                    labelSelector:\n                      description: |-\n                        LabelSelector is used to find matching pods.\n                        Pods that match this label selector are counted to determine the number of pods\n                        in their corresponding topology domain.\n                      properties:\n                        matchExpressions:\n                          description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                          items:\n                            description: |-\n                              A label selector requirement is a selector that contains values, a key, and an operator that\n                              relates the key and values.\n                            properties:\n                              key:\n                                description: key is the label key that the selector applies to.\n                                type: string\n                              operator:\n                                description: |-\n                                  operator represents a key's relationship to a set of values.\n                                  Valid operators are In, NotIn, Exists and DoesNotExist.\n                                type: string\n                              values:\n                                description: |-\n                                  values is an array of string values. If the operator is In or NotIn,\n                                  the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                  the values array must be empty. This array is replaced during a strategic\n                                  merge patch.\n                                items:\n                                  type: string\n                                type: array\n                                x-kubernetes-list-type: atomic\n                            required:\n                            - key\n                            - operator\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        matchLabels:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                            map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                            operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                          type: object\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    matchLabelKeys:\n                      description: |-\n                        MatchLabelKeys is a set of pod label keys to select the pods over which\n                        spreading will be calculated. The keys are used to lookup values from the\n                        incoming pod labels, those key-value labels are ANDed with labelSelector\n                        to select the group of existing pods over which spreading will be calculated\n                        for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector.\n                        MatchLabelKeys cannot be set when LabelSelector isn't set.\n                        Keys that don't exist in the incoming pod labels will\n                        be ignored. A null or empty list means only match against labelSelector.\n\n                        This is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default).\n                      items:\n                        type: string\n                      type: array\n                      x-kubernetes-list-type: atomic\n                    maxSkew:\n                      description: |-\n                        MaxSkew describes the degree to which pods may be unevenly distributed.\n                        When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference\n                        between the number of matching pods in the target topology and the global minimum.\n                        The global minimum is the minimum number of matching pods in an eligible domain\n                        or zero if the number of eligible domains is less than MinDomains.\n                        For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same\n                        labelSelector spread as 2/2/1:\n                        In this case, the global minimum is 1.\n                        | zone1 | zone2 | zone3 |\n                        |  P P  |  P P  |   P   |\n                        - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2;\n                        scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2)\n                        violate MaxSkew(1).\n                        - if MaxSkew is 2, incoming pod can be scheduled onto any zone.\n                        When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence\n                        to topologies that satisfy it.\n                        It's a required field. Default value is 1 and 0 is not allowed.\n                      format: int32\n                      type: integer\n                    minDomains:\n                      description: |-\n                        MinDomains indicates a minimum number of eligible domains.\n                        When the number of eligible domains with matching topology keys is less than minDomains,\n                        Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed.\n                        And when the number of eligible domains with matching topology keys equals or greater than minDomains,\n                        this value has no effect on scheduling.\n                        As a result, when the number of eligible domains is less than minDomains,\n                        scheduler won't schedule more than maxSkew Pods to those domains.\n                        If value is nil, the constraint behaves as if MinDomains is equal to 1.\n                        Valid values are integers greater than 0.\n                        When value is not nil, WhenUnsatisfiable must be DoNotSchedule.\n\n                        For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same\n                        labelSelector spread as 2/2/2:\n                        | zone1 | zone2 | zone3 |\n                        |  P P  |  P P  |  P P  |\n                        The number of domains is less than 5(MinDomains), so \"global minimum\" is treated as 0.\n                        In this situation, new pod with the same labelSelector cannot be scheduled,\n                        because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones,\n                        it will violate MaxSkew.\n                      format: int32\n                      type: integer\n                    nodeAffinityPolicy:\n                      description: |-\n                        NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector\n                        when calculating pod topology spread skew. Options are:\n                        - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations.\n                        - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.\n\n                        If this value is nil, the behavior is equivalent to the Honor policy.\n                      type: string\n                    nodeTaintsPolicy:\n                      description: |-\n                        NodeTaintsPolicy indicates how we will treat node taints when calculating\n                        pod topology spread skew. Options are:\n                        - Honor: nodes without taints, along with tainted nodes for which the incoming pod\n                        has a toleration, are included.\n                        - Ignore: node taints are ignored. All nodes are included.\n\n                        If this value is nil, the behavior is equivalent to the Ignore policy.\n                      type: string\n                    topologyKey:\n                      description: |-\n                        TopologyKey is the key of node labels. Nodes that have a label with this key\n                        and identical values are considered to be in the same topology.\n                        We consider each <key, value> as a \"bucket\", and try to put balanced number\n                        of pods into each bucket.\n                        We define a domain as a particular instance of a topology.\n                        Also, we define an eligible domain as a domain whose nodes meet the requirements of\n                        nodeAffinityPolicy and nodeTaintsPolicy.\n                        e.g. If TopologyKey is \"kubernetes.io/hostname\", each Node is a domain of that topology.\n                        And, if TopologyKey is \"topology.kubernetes.io/zone\", each zone is a domain of that topology.\n                        It's a required field.\n                      type: string\n                    whenUnsatisfiable:\n                      description: |-\n                        WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy\n                        the spread constraint.\n                        - DoNotSchedule (default) tells the scheduler not to schedule it.\n                        - ScheduleAnyway tells the scheduler to schedule the pod in any location,\n                          but giving higher precedence to topologies that would help reduce the\n                          skew.\n                        A constraint is considered \"Unsatisfiable\" for an incoming pod\n                        if and only if every possible node assignment for that pod would violate\n                        \"MaxSkew\" on some topology.\n                        For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same\n                        labelSelector spread as 3/1/1:\n                        | zone1 | zone2 | zone3 |\n                        | P P P |   P   |   P   |\n                        If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled\n                        to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies\n                        MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler\n                        won't make it *more* imbalanced.\n                        It's a required field.\n                      type: string\n                  required:\n                  - maxSkew\n                  - topologyKey\n                  - whenUnsatisfiable\n                  type: object\n                type: array\n              tracingConfig:\n                description: |-\n                  Configures tracing.\n\n                  The configuration format is defined at https://thanos.io/tip/thanos/tracing.md/#configuration\n\n                  This is an *experimental feature*, it may change in any upcoming release\n                  in a breaking way.\n\n                  The operator performs no validation of the configuration.\n\n                  `tracingConfigFile` takes precedence over this field.\n                properties:\n                  key:\n                    description: The key of the secret to select from.  Must be a valid secret key.\n                    type: string\n                  name:\n                    default: \"\"\n                    description: |-\n                      Name of the referent.\n                      This field is effectively required, but due to backwards compatibility is\n                      allowed to be empty. Instances of this type with an empty value here are\n                      almost certainly wrong.\n                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                    type: string\n                  optional:\n                    description: Specify whether the Secret or its key must be defined\n                    type: boolean\n                required:\n                - key\n                type: object\n                x-kubernetes-map-type: atomic\n              tracingConfigFile:\n                description: |-\n                  Configures the path of the tracing configuration file.\n\n                  The configuration format is defined at https://thanos.io/tip/thanos/tracing.md/#configuration\n\n                  This is an *experimental feature*, it may change in any upcoming release\n                  in a breaking way.\n\n                  The operator performs no validation of the configuration file.\n\n                  This field takes precedence over `tracingConfig`.\n                type: string\n              version:\n                description: Version of Thanos to be deployed.\n                type: string\n              volumeMounts:\n                description: |-\n                  VolumeMounts allows configuration of additional VolumeMounts on the output StatefulSet definition.\n                  VolumeMounts specified will be appended to other VolumeMounts in the ruler container,\n                  that are generated as a result of StorageSpec objects.\n                items:\n                  description: VolumeMount describes a mounting of a Volume within a container.\n                  properties:\n                    mountPath:\n                      description: |-\n                        Path within the container at which the volume should be mounted.  Must\n                        not contain ':'.\n                      type: string\n                    mountPropagation:\n                      description: |-\n                        mountPropagation determines how mounts are propagated from the host\n                        to container and the other way around.\n                        When not set, MountPropagationNone is used.\n                        This field is beta in 1.10.\n                        When RecursiveReadOnly is set to IfPossible or to Enabled, MountPropagation must be None or unspecified\n                        (which defaults to None).\n                      type: string\n                    name:\n                      description: This must match the Name of a Volume.\n                      type: string\n                    readOnly:\n                      description: |-\n                        Mounted read-only if true, read-write otherwise (false or unspecified).\n                        Defaults to false.\n                      type: boolean\n                    recursiveReadOnly:\n                      description: |-\n                        RecursiveReadOnly specifies whether read-only mounts should be handled\n                        recursively.\n\n                        If ReadOnly is false, this field has no meaning and must be unspecified.\n\n                        If ReadOnly is true, and this field is set to Disabled, the mount is not made\n                        recursively read-only.  If this field is set to IfPossible, the mount is made\n                        recursively read-only, if it is supported by the container runtime.  If this\n                        field is set to Enabled, the mount is made recursively read-only if it is\n                        supported by the container runtime, otherwise the pod will not be started and\n                        an error will be generated to indicate the reason.\n\n                        If this field is set to IfPossible or Enabled, MountPropagation must be set to\n                        None (or be unspecified, which defaults to None).\n\n                        If this field is not specified, it is treated as an equivalent of Disabled.\n                      type: string\n                    subPath:\n                      description: |-\n                        Path within the volume from which the container's volume should be mounted.\n                        Defaults to \"\" (volume's root).\n                      type: string\n                    subPathExpr:\n                      description: |-\n                        Expanded path within the volume from which the container's volume should be mounted.\n                        Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment.\n                        Defaults to \"\" (volume's root).\n                        SubPathExpr and SubPath are mutually exclusive.\n                      type: string\n                  required:\n                  - mountPath\n                  - name\n                  type: object\n                type: array\n              volumes:\n                description: |-\n                  Volumes allows configuration of additional volumes on the output StatefulSet definition. Volumes specified will\n                  be appended to other volumes that are generated as a result of StorageSpec objects.\n                items:\n                  description: Volume represents a named volume in a pod that may be accessed by any container in the pod.\n                  properties:\n                    awsElasticBlockStore:\n                      description: |-\n                        awsElasticBlockStore represents an AWS Disk resource that is attached to a\n                        kubelet's host machine and then exposed to the pod.\n                        Deprecated: AWSElasticBlockStore is deprecated. All operations for the in-tree\n                        awsElasticBlockStore type are redirected to the ebs.csi.aws.com CSI driver.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                          type: string\n                        partition:\n                          description: |-\n                            partition is the partition in the volume that you want to mount.\n                            If omitted, the default is to mount by volume name.\n                            Examples: For volume /dev/sda1, you specify the partition as \"1\".\n                            Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty).\n                          format: int32\n                          type: integer\n                        readOnly:\n                          description: |-\n                            readOnly value true will force the readOnly setting in VolumeMounts.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                          type: boolean\n                        volumeID:\n                          description: |-\n                            volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume).\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore\n                          type: string\n                      required:\n                      - volumeID\n                      type: object\n                    azureDisk:\n                      description: |-\n                        azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.\n                        Deprecated: AzureDisk is deprecated. All operations for the in-tree azureDisk type\n                        are redirected to the disk.csi.azure.com CSI driver.\n                      properties:\n                        cachingMode:\n                          description: 'cachingMode is the Host Caching mode: None, Read Only, Read Write.'\n                          type: string\n                        diskName:\n                          description: diskName is the Name of the data disk in the blob storage\n                          type: string\n                        diskURI:\n                          description: diskURI is the URI of data disk in the blob storage\n                          type: string\n                        fsType:\n                          default: ext4\n                          description: |-\n                            fsType is Filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        kind:\n                          description: 'kind expected values are Shared: multiple blob disks per storage account  Dedicated: single blob disk per storage account  Managed: azure managed data disk (only in managed availability set). defaults to shared'\n                          type: string\n                        readOnly:\n                          default: false\n                          description: |-\n                            readOnly Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                      required:\n                      - diskName\n                      - diskURI\n                      type: object\n                    azureFile:\n                      description: |-\n                        azureFile represents an Azure File Service mount on the host and bind mount to the pod.\n                        Deprecated: AzureFile is deprecated. All operations for the in-tree azureFile type\n                        are redirected to the file.csi.azure.com CSI driver.\n                      properties:\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretName:\n                          description: secretName is the  name of secret that contains Azure Storage Account Name and Key\n                          type: string\n                        shareName:\n                          description: shareName is the azure share Name\n                          type: string\n                      required:\n                      - secretName\n                      - shareName\n                      type: object\n                    cephfs:\n                      description: |-\n                        cephFS represents a Ceph FS mount on the host that shares a pod's lifetime.\n                        Deprecated: CephFS is deprecated and the in-tree cephfs type is no longer supported.\n                      properties:\n                        monitors:\n                          description: |-\n                            monitors is Required: Monitors is a collection of Ceph monitors\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        path:\n                          description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /'\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly is Optional: Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          type: boolean\n                        secretFile:\n                          description: |-\n                            secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          type: string\n                        secretRef:\n                          description: |-\n                            secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty.\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        user:\n                          description: |-\n                            user is optional: User is the rados user name, default is admin\n                            More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it\n                          type: string\n                      required:\n                      - monitors\n                      type: object\n                    cinder:\n                      description: |-\n                        cinder represents a cinder volume attached and mounted on kubelets host machine.\n                        Deprecated: Cinder is deprecated. All operations for the in-tree cinder type\n                        are redirected to the cinder.csi.openstack.org CSI driver.\n                        More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                            More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef is optional: points to a secret object containing parameters used to connect\n                            to OpenStack.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        volumeID:\n                          description: |-\n                            volumeID used to identify the volume in cinder.\n                            More info: https://examples.k8s.io/mysql-cinder-pd/README.md\n                          type: string\n                      required:\n                      - volumeID\n                      type: object\n                    configMap:\n                      description: configMap represents a configMap that should populate this volume\n                      properties:\n                        defaultMode:\n                          description: |-\n                            defaultMode is optional: mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                            Defaults to 0644.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        items:\n                          description: |-\n                            items if unspecified, each key-value pair in the Data field of the referenced\n                            ConfigMap will be projected into the volume as a file whose name is the\n                            key and content is the value. If specified, the listed keys will be\n                            projected into the specified paths, and unlisted keys will not be\n                            present. If a key is specified which is not present in the ConfigMap,\n                            the volume setup will error unless it is marked optional. Paths must be\n                            relative and may not contain the '..' path or start with '..'.\n                          items:\n                            description: Maps a string key to a path within a volume.\n                            properties:\n                              key:\n                                description: key is the key to project.\n                                type: string\n                              mode:\n                                description: |-\n                                  mode is Optional: mode bits used to set permissions on this file.\n                                  Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                  YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                  If not specified, the volume defaultMode will be used.\n                                  This might be in conflict with other options that affect the file\n                                  mode, like fsGroup, and the result can be other mode bits set.\n                                format: int32\n                                type: integer\n                              path:\n                                description: |-\n                                  path is the relative path of the file to map the key to.\n                                  May not be an absolute path.\n                                  May not contain the path element '..'.\n                                  May not start with the string '..'.\n                                type: string\n                            required:\n                            - key\n                            - path\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        name:\n                          default: \"\"\n                          description: |-\n                            Name of the referent.\n                            This field is effectively required, but due to backwards compatibility is\n                            allowed to be empty. Instances of this type with an empty value here are\n                            almost certainly wrong.\n                            More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                          type: string\n                        optional:\n                          description: optional specify whether the ConfigMap or its keys must be defined\n                          type: boolean\n                      type: object\n                      x-kubernetes-map-type: atomic\n                    csi:\n                      description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers.\n                      properties:\n                        driver:\n                          description: |-\n                            driver is the name of the CSI driver that handles this volume.\n                            Consult with your admin for the correct name as registered in the cluster.\n                          type: string\n                        fsType:\n                          description: |-\n                            fsType to mount. Ex. \"ext4\", \"xfs\", \"ntfs\".\n                            If not provided, the empty value is passed to the associated CSI driver\n                            which will determine the default filesystem to apply.\n                          type: string\n                        nodePublishSecretRef:\n                          description: |-\n                            nodePublishSecretRef is a reference to the secret object containing\n                            sensitive information to pass to the CSI driver to complete the CSI\n                            NodePublishVolume and NodeUnpublishVolume calls.\n                            This field is optional, and  may be empty if no secret is required. If the\n                            secret object contains more than one secret, all secret references are passed.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        readOnly:\n                          description: |-\n                            readOnly specifies a read-only configuration for the volume.\n                            Defaults to false (read/write).\n                          type: boolean\n                        volumeAttributes:\n                          additionalProperties:\n                            type: string\n                          description: |-\n                            volumeAttributes stores driver-specific properties that are passed to the CSI\n                            driver. Consult your driver's documentation for supported values.\n                          type: object\n                      required:\n                      - driver\n                      type: object\n                    downwardAPI:\n                      description: downwardAPI represents downward API about the pod that should populate this volume\n                      properties:\n                        defaultMode:\n                          description: |-\n                            Optional: mode bits to use on created files by default. Must be a\n                            Optional: mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                            Defaults to 0644.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        items:\n                          description: Items is a list of downward API volume file\n                          items:\n                            description: DownwardAPIVolumeFile represents information to create the file containing the pod field\n                            properties:\n                              fieldRef:\n                                description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.'\n                                properties:\n                                  apiVersion:\n                                    description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                    type: string\n                                  fieldPath:\n                                    description: Path of the field to select in the specified API version.\n                                    type: string\n                                required:\n                                - fieldPath\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              mode:\n                                description: |-\n                                  Optional: mode bits used to set permissions on this file, must be an octal value\n                                  between 0000 and 0777 or a decimal value between 0 and 511.\n                                  YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                  If not specified, the volume defaultMode will be used.\n                                  This might be in conflict with other options that affect the file\n                                  mode, like fsGroup, and the result can be other mode bits set.\n                                format: int32\n                                type: integer\n                              path:\n                                description: 'Required: Path is  the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..'''\n                                type: string\n                              resourceFieldRef:\n                                description: |-\n                                  Selects a resource of the container: only resources limits and requests\n                                  (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.\n                                properties:\n                                  containerName:\n                                    description: 'Container name: required for volumes, optional for env vars'\n                                    type: string\n                                  divisor:\n                                    anyOf:\n                                    - type: integer\n                                    - type: string\n                                    description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                    pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                    x-kubernetes-int-or-string: true\n                                  resource:\n                                    description: 'Required: resource to select'\n                                    type: string\n                                required:\n                                - resource\n                                type: object\n                                x-kubernetes-map-type: atomic\n                            required:\n                            - path\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    emptyDir:\n                      description: |-\n                        emptyDir represents a temporary directory that shares a pod's lifetime.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                      properties:\n                        medium:\n                          description: |-\n                            medium represents what type of storage medium should back this directory.\n                            The default is \"\" which means to use the node's default medium.\n                            Must be an empty string (default) or Memory.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                          type: string\n                        sizeLimit:\n                          anyOf:\n                          - type: integer\n                          - type: string\n                          description: |-\n                            sizeLimit is the total amount of local storage required for this EmptyDir volume.\n                            The size limit is also applicable for memory medium.\n                            The maximum usage on memory medium EmptyDir would be the minimum value between\n                            the SizeLimit specified here and the sum of memory limits of all containers in a pod.\n                            The default is nil which means that the limit is undefined.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir\n                          pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                          x-kubernetes-int-or-string: true\n                      type: object\n                    ephemeral:\n                      description: |-\n                        ephemeral represents a volume that is handled by a cluster storage driver.\n                        The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts,\n                        and deleted when the pod is removed.\n\n                        Use this if:\n                        a) the volume is only needed while the pod runs,\n                        b) features of normal volumes like restoring from snapshot or capacity\n                           tracking are needed,\n                        c) the storage driver is specified through a storage class, and\n                        d) the storage driver supports dynamic volume provisioning through\n                           a PersistentVolumeClaim (see EphemeralVolumeSource for more\n                           information on the connection between this volume type\n                           and PersistentVolumeClaim).\n\n                        Use PersistentVolumeClaim or one of the vendor-specific\n                        APIs for volumes that persist for longer than the lifecycle\n                        of an individual pod.\n\n                        Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to\n                        be used that way - see the documentation of the driver for\n                        more information.\n\n                        A pod can use both types of ephemeral volumes and\n                        persistent volumes at the same time.\n                      properties:\n                        volumeClaimTemplate:\n                          description: |-\n                            Will be used to create a stand-alone PVC to provision the volume.\n                            The pod in which this EphemeralVolumeSource is embedded will be the\n                            owner of the PVC, i.e. the PVC will be deleted together with the\n                            pod.  The name of the PVC will be `<pod name>-<volume name>` where\n                            `<volume name>` is the name from the `PodSpec.Volumes` array\n                            entry. Pod validation will reject the pod if the concatenated name\n                            is not valid for a PVC (for example, too long).\n\n                            An existing PVC with that name that is not owned by the pod\n                            will *not* be used for the pod to avoid using an unrelated\n                            volume by mistake. Starting the pod is then blocked until\n                            the unrelated PVC is removed. If such a pre-created PVC is\n                            meant to be used by the pod, the PVC has to updated with an\n                            owner reference to the pod once the pod exists. Normally\n                            this should not be necessary, but it may be useful when\n                            manually reconstructing a broken cluster.\n\n                            This field is read-only and no changes will be made by Kubernetes\n                            to the PVC after it has been created.\n\n                            Required, must not be nil.\n                          properties:\n                            metadata:\n                              description: |-\n                                May contain labels and annotations that will be copied into the PVC\n                                when creating it. No other fields are allowed and will be rejected during\n                                validation.\n                              type: object\n                            spec:\n                              description: |-\n                                The specification for the PersistentVolumeClaim. The entire content is\n                                copied unchanged into the PVC that gets created from this\n                                template. The same fields as in a PersistentVolumeClaim\n                                are also valid here.\n                              properties:\n                                accessModes:\n                                  description: |-\n                                    accessModes contains the desired access modes the volume should have.\n                                    More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1\n                                  items:\n                                    type: string\n                                  type: array\n                                  x-kubernetes-list-type: atomic\n                                dataSource:\n                                  description: |-\n                                    dataSource field can be used to specify either:\n                                    * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot)\n                                    * An existing PVC (PersistentVolumeClaim)\n                                    If the provisioner or an external controller can support the specified data source,\n                                    it will create a new volume based on the contents of the specified data source.\n                                    When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef,\n                                    and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified.\n                                    If the namespace is specified, then dataSourceRef will not be copied to dataSource.\n                                  properties:\n                                    apiGroup:\n                                      description: |-\n                                        APIGroup is the group for the resource being referenced.\n                                        If APIGroup is not specified, the specified Kind must be in the core API group.\n                                        For any other third-party types, APIGroup is required.\n                                      type: string\n                                    kind:\n                                      description: Kind is the type of resource being referenced\n                                      type: string\n                                    name:\n                                      description: Name is the name of resource being referenced\n                                      type: string\n                                  required:\n                                  - kind\n                                  - name\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                dataSourceRef:\n                                  description: |-\n                                    dataSourceRef specifies the object from which to populate the volume with data, if a non-empty\n                                    volume is desired. This may be any object from a non-empty API group (non\n                                    core object) or a PersistentVolumeClaim object.\n                                    When this field is specified, volume binding will only succeed if the type of\n                                    the specified object matches some installed volume populator or dynamic\n                                    provisioner.\n                                    This field will replace the functionality of the dataSource field and as such\n                                    if both fields are non-empty, they must have the same value. For backwards\n                                    compatibility, when namespace isn't specified in dataSourceRef,\n                                    both fields (dataSource and dataSourceRef) will be set to the same\n                                    value automatically if one of them is empty and the other is non-empty.\n                                    When namespace is specified in dataSourceRef,\n                                    dataSource isn't set to the same value and must be empty.\n                                    There are three important differences between dataSource and dataSourceRef:\n                                    * While dataSource only allows two specific types of objects, dataSourceRef\n                                      allows any non-core object, as well as PersistentVolumeClaim objects.\n                                    * While dataSource ignores disallowed values (dropping them), dataSourceRef\n                                      preserves all values, and generates an error if a disallowed value is\n                                      specified.\n                                    * While dataSource only allows local objects, dataSourceRef allows objects\n                                      in any namespaces.\n                                    (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled.\n                                    (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                  properties:\n                                    apiGroup:\n                                      description: |-\n                                        APIGroup is the group for the resource being referenced.\n                                        If APIGroup is not specified, the specified Kind must be in the core API group.\n                                        For any other third-party types, APIGroup is required.\n                                      type: string\n                                    kind:\n                                      description: Kind is the type of resource being referenced\n                                      type: string\n                                    name:\n                                      description: Name is the name of resource being referenced\n                                      type: string\n                                    namespace:\n                                      description: |-\n                                        Namespace is the namespace of resource being referenced\n                                        Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.\n                                        (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled.\n                                      type: string\n                                  required:\n                                  - kind\n                                  - name\n                                  type: object\n                                resources:\n                                  description: |-\n                                    resources represents the minimum resources the volume should have.\n                                    If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements\n                                    that are lower than previous value but must still be higher than capacity recorded in the\n                                    status field of the claim.\n                                    More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources\n                                  properties:\n                                    limits:\n                                      additionalProperties:\n                                        anyOf:\n                                        - type: integer\n                                        - type: string\n                                        pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                        x-kubernetes-int-or-string: true\n                                      description: |-\n                                        Limits describes the maximum amount of compute resources allowed.\n                                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                      type: object\n                                    requests:\n                                      additionalProperties:\n                                        anyOf:\n                                        - type: integer\n                                        - type: string\n                                        pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                        x-kubernetes-int-or-string: true\n                                      description: |-\n                                        Requests describes the minimum amount of compute resources required.\n                                        If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\n                                        otherwise to an implementation-defined value. Requests cannot exceed Limits.\n                                        More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\n                                      type: object\n                                  type: object\n                                selector:\n                                  description: selector is a label query over volumes to consider for binding.\n                                  properties:\n                                    matchExpressions:\n                                      description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                      items:\n                                        description: |-\n                                          A label selector requirement is a selector that contains values, a key, and an operator that\n                                          relates the key and values.\n                                        properties:\n                                          key:\n                                            description: key is the label key that the selector applies to.\n                                            type: string\n                                          operator:\n                                            description: |-\n                                              operator represents a key's relationship to a set of values.\n                                              Valid operators are In, NotIn, Exists and DoesNotExist.\n                                            type: string\n                                          values:\n                                            description: |-\n                                              values is an array of string values. If the operator is In or NotIn,\n                                              the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                              the values array must be empty. This array is replaced during a strategic\n                                              merge patch.\n                                            items:\n                                              type: string\n                                            type: array\n                                            x-kubernetes-list-type: atomic\n                                        required:\n                                        - key\n                                        - operator\n                                        type: object\n                                      type: array\n                                      x-kubernetes-list-type: atomic\n                                    matchLabels:\n                                      additionalProperties:\n                                        type: string\n                                      description: |-\n                                        matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                        map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                        operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                      type: object\n                                  type: object\n                                  x-kubernetes-map-type: atomic\n                                storageClassName:\n                                  description: |-\n                                    storageClassName is the name of the StorageClass required by the claim.\n                                    More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1\n                                  type: string\n                                volumeAttributesClassName:\n                                  description: |-\n                                    volumeAttributesClassName may be used to set the VolumeAttributesClass used by this claim.\n                                    If specified, the CSI driver will create or update the volume with the attributes defined\n                                    in the corresponding VolumeAttributesClass. This has a different purpose than storageClassName,\n                                    it can be changed after the claim is created. An empty string value means that no VolumeAttributesClass\n                                    will be applied to the claim but it's not allowed to reset this field to empty string once it is set.\n                                    If unspecified and the PersistentVolumeClaim is unbound, the default VolumeAttributesClass\n                                    will be set by the persistentvolume controller if it exists.\n                                    If the resource referred to by volumeAttributesClass does not exist, this PersistentVolumeClaim will be\n                                    set to a Pending state, as reflected by the modifyVolumeStatus field, until such as a resource\n                                    exists.\n                                    More info: https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/\n                                    (Beta) Using this field requires the VolumeAttributesClass feature gate to be enabled (off by default).\n                                  type: string\n                                volumeMode:\n                                  description: |-\n                                    volumeMode defines what type of volume is required by the claim.\n                                    Value of Filesystem is implied when not included in claim spec.\n                                  type: string\n                                volumeName:\n                                  description: volumeName is the binding reference to the PersistentVolume backing this claim.\n                                  type: string\n                              type: object\n                          required:\n                          - spec\n                          type: object\n                      type: object\n                    fc:\n                      description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        lun:\n                          description: 'lun is Optional: FC target lun number'\n                          format: int32\n                          type: integer\n                        readOnly:\n                          description: |-\n                            readOnly is Optional: Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        targetWWNs:\n                          description: 'targetWWNs is Optional: FC target worldwide names (WWNs)'\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        wwids:\n                          description: |-\n                            wwids Optional: FC volume world wide identifiers (wwids)\n                            Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    flexVolume:\n                      description: |-\n                        flexVolume represents a generic volume resource that is\n                        provisioned/attached using an exec based plugin.\n                        Deprecated: FlexVolume is deprecated. Consider using a CSIDriver instead.\n                      properties:\n                        driver:\n                          description: driver is the name of the driver to use for this volume.\n                          type: string\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". The default filesystem depends on FlexVolume script.\n                          type: string\n                        options:\n                          additionalProperties:\n                            type: string\n                          description: 'options is Optional: this field holds extra command options if any.'\n                          type: object\n                        readOnly:\n                          description: |-\n                            readOnly is Optional: defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef is Optional: secretRef is reference to the secret object containing\n                            sensitive information to pass to the plugin scripts. This may be\n                            empty if no secret object is specified. If the secret object\n                            contains more than one secret, all secrets are passed to the plugin\n                            scripts.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                      required:\n                      - driver\n                      type: object\n                    flocker:\n                      description: |-\n                        flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running.\n                        Deprecated: Flocker is deprecated and the in-tree flocker type is no longer supported.\n                      properties:\n                        datasetName:\n                          description: |-\n                            datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker\n                            should be considered as deprecated\n                          type: string\n                        datasetUUID:\n                          description: datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset\n                          type: string\n                      type: object\n                    gcePersistentDisk:\n                      description: |-\n                        gcePersistentDisk represents a GCE Disk resource that is attached to a\n                        kubelet's host machine and then exposed to the pod.\n                        Deprecated: GCEPersistentDisk is deprecated. All operations for the in-tree\n                        gcePersistentDisk type are redirected to the pd.csi.storage.gke.io CSI driver.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          type: string\n                        partition:\n                          description: |-\n                            partition is the partition in the volume that you want to mount.\n                            If omitted, the default is to mount by volume name.\n                            Examples: For volume /dev/sda1, you specify the partition as \"1\".\n                            Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty).\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          format: int32\n                          type: integer\n                        pdName:\n                          description: |-\n                            pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the ReadOnly setting in VolumeMounts.\n                            Defaults to false.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk\n                          type: boolean\n                      required:\n                      - pdName\n                      type: object\n                    gitRepo:\n                      description: |-\n                        gitRepo represents a git repository at a particular revision.\n                        Deprecated: GitRepo is deprecated. To provision a container with a git repo, mount an\n                        EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir\n                        into the Pod's container.\n                      properties:\n                        directory:\n                          description: |-\n                            directory is the target directory name.\n                            Must not contain or start with '..'.  If '.' is supplied, the volume directory will be the\n                            git repository.  Otherwise, if specified, the volume will contain the git repository in\n                            the subdirectory with the given name.\n                          type: string\n                        repository:\n                          description: repository is the URL\n                          type: string\n                        revision:\n                          description: revision is the commit hash for the specified revision.\n                          type: string\n                      required:\n                      - repository\n                      type: object\n                    glusterfs:\n                      description: |-\n                        glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime.\n                        Deprecated: Glusterfs is deprecated and the in-tree glusterfs type is no longer supported.\n                        More info: https://examples.k8s.io/volumes/glusterfs/README.md\n                      properties:\n                        endpoints:\n                          description: |-\n                            endpoints is the endpoint name that details Glusterfs topology.\n                            More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod\n                          type: string\n                        path:\n                          description: |-\n                            path is the Glusterfs volume path.\n                            More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the Glusterfs volume to be mounted with read-only permissions.\n                            Defaults to false.\n                            More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod\n                          type: boolean\n                      required:\n                      - endpoints\n                      - path\n                      type: object\n                    hostPath:\n                      description: |-\n                        hostPath represents a pre-existing file or directory on the host\n                        machine that is directly exposed to the container. This is generally\n                        used for system agents or other privileged things that are allowed\n                        to see the host machine. Most containers will NOT need this.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath\n                      properties:\n                        path:\n                          description: |-\n                            path of the directory on the host.\n                            If the path is a symlink, it will follow the link to the real path.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath\n                          type: string\n                        type:\n                          description: |-\n                            type for HostPath Volume\n                            Defaults to \"\"\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath\n                          type: string\n                      required:\n                      - path\n                      type: object\n                    image:\n                      description: |-\n                        image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine.\n                        The volume is resolved at pod startup depending on which PullPolicy value is provided:\n\n                        - Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails.\n                        - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.\n                        - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n\n                        The volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation.\n                        A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message.\n                        The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field.\n                        The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images.\n                        The volume will be mounted read-only (ro) and non-executable files (noexec).\n                        Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33.\n                        The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.\n                      properties:\n                        pullPolicy:\n                          description: |-\n                            Policy for pulling OCI objects. Possible values are:\n                            Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails.\n                            Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.\n                            IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n                            Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.\n                          type: string\n                        reference:\n                          description: |-\n                            Required: Image or artifact reference to be used.\n                            Behaves in the same way as pod.spec.containers[*].image.\n                            Pull secrets will be assembled in the same way as for the container image by looking up node credentials, SA image pull secrets, and pod spec image pull secrets.\n                            More info: https://kubernetes.io/docs/concepts/containers/images\n                            This field is optional to allow higher level config management to default or override\n                            container images in workload controllers like Deployments and StatefulSets.\n                          type: string\n                      type: object\n                    iscsi:\n                      description: |-\n                        iscsi represents an ISCSI Disk resource that is attached to a\n                        kubelet's host machine and then exposed to the pod.\n                        More info: https://examples.k8s.io/volumes/iscsi/README.md\n                      properties:\n                        chapAuthDiscovery:\n                          description: chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication\n                          type: boolean\n                        chapAuthSession:\n                          description: chapAuthSession defines whether support iSCSI Session CHAP authentication\n                          type: boolean\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi\n                          type: string\n                        initiatorName:\n                          description: |-\n                            initiatorName is the custom iSCSI Initiator Name.\n                            If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface\n                            <target portal>:<volume name> will be created for the connection.\n                          type: string\n                        iqn:\n                          description: iqn is the target iSCSI Qualified Name.\n                          type: string\n                        iscsiInterface:\n                          default: default\n                          description: |-\n                            iscsiInterface is the interface Name that uses an iSCSI transport.\n                            Defaults to 'default' (tcp).\n                          type: string\n                        lun:\n                          description: lun represents iSCSI Target Lun number.\n                          format: int32\n                          type: integer\n                        portals:\n                          description: |-\n                            portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port\n                            is other than default (typically TCP ports 860 and 3260).\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        readOnly:\n                          description: |-\n                            readOnly here will force the ReadOnly setting in VolumeMounts.\n                            Defaults to false.\n                          type: boolean\n                        secretRef:\n                          description: secretRef is the CHAP Secret for iSCSI target and initiator authentication\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        targetPortal:\n                          description: |-\n                            targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port\n                            is other than default (typically TCP ports 860 and 3260).\n                          type: string\n                      required:\n                      - iqn\n                      - lun\n                      - targetPortal\n                      type: object\n                    name:\n                      description: |-\n                        name of the volume.\n                        Must be a DNS_LABEL and unique within the pod.\n                        More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                      type: string\n                    nfs:\n                      description: |-\n                        nfs represents an NFS mount on the host that shares a pod's lifetime\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                      properties:\n                        path:\n                          description: |-\n                            path that is exported by the NFS server.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the NFS export to be mounted with read-only permissions.\n                            Defaults to false.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                          type: boolean\n                        server:\n                          description: |-\n                            server is the hostname or IP address of the NFS server.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs\n                          type: string\n                      required:\n                      - path\n                      - server\n                      type: object\n                    persistentVolumeClaim:\n                      description: |-\n                        persistentVolumeClaimVolumeSource represents a reference to a\n                        PersistentVolumeClaim in the same namespace.\n                        More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims\n                      properties:\n                        claimName:\n                          description: |-\n                            claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume.\n                            More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly Will force the ReadOnly setting in VolumeMounts.\n                            Default false.\n                          type: boolean\n                      required:\n                      - claimName\n                      type: object\n                    photonPersistentDisk:\n                      description: |-\n                        photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine.\n                        Deprecated: PhotonPersistentDisk is deprecated and the in-tree photonPersistentDisk type is no longer supported.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        pdID:\n                          description: pdID is the ID that identifies Photon Controller persistent disk\n                          type: string\n                      required:\n                      - pdID\n                      type: object\n                    portworxVolume:\n                      description: |-\n                        portworxVolume represents a portworx volume attached and mounted on kubelets host machine.\n                        Deprecated: PortworxVolume is deprecated. All operations for the in-tree portworxVolume type\n                        are redirected to the pxd.portworx.com CSI driver when the CSIMigrationPortworx feature-gate\n                        is on.\n                      properties:\n                        fsType:\n                          description: |-\n                            fSType represents the filesystem type to mount\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        volumeID:\n                          description: volumeID uniquely identifies a Portworx volume\n                          type: string\n                      required:\n                      - volumeID\n                      type: object\n                    projected:\n                      description: projected items for all in one resources secrets, configmaps, and downward API\n                      properties:\n                        defaultMode:\n                          description: |-\n                            defaultMode are the mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        sources:\n                          description: |-\n                            sources is the list of volume projections. Each entry in this list\n                            handles one source.\n                          items:\n                            description: |-\n                              Projection that may be projected along with other supported volume types.\n                              Exactly one of these fields must be set.\n                            properties:\n                              clusterTrustBundle:\n                                description: |-\n                                  ClusterTrustBundle allows a pod to access the `.spec.trustBundle` field\n                                  of ClusterTrustBundle objects in an auto-updating file.\n\n                                  Alpha, gated by the ClusterTrustBundleProjection feature gate.\n\n                                  ClusterTrustBundle objects can either be selected by name, or by the\n                                  combination of signer name and a label selector.\n\n                                  Kubelet performs aggressive normalization of the PEM contents written\n                                  into the pod filesystem.  Esoteric PEM features such as inter-block\n                                  comments and block headers are stripped.  Certificates are deduplicated.\n                                  The ordering of certificates within the file is arbitrary, and Kubelet\n                                  may change the order over time.\n                                properties:\n                                  labelSelector:\n                                    description: |-\n                                      Select all ClusterTrustBundles that match this label selector.  Only has\n                                      effect if signerName is set.  Mutually-exclusive with name.  If unset,\n                                      interpreted as \"match nothing\".  If set but empty, interpreted as \"match\n                                      everything\".\n                                    properties:\n                                      matchExpressions:\n                                        description: matchExpressions is a list of label selector requirements. The requirements are ANDed.\n                                        items:\n                                          description: |-\n                                            A label selector requirement is a selector that contains values, a key, and an operator that\n                                            relates the key and values.\n                                          properties:\n                                            key:\n                                              description: key is the label key that the selector applies to.\n                                              type: string\n                                            operator:\n                                              description: |-\n                                                operator represents a key's relationship to a set of values.\n                                                Valid operators are In, NotIn, Exists and DoesNotExist.\n                                              type: string\n                                            values:\n                                              description: |-\n                                                values is an array of string values. If the operator is In or NotIn,\n                                                the values array must be non-empty. If the operator is Exists or DoesNotExist,\n                                                the values array must be empty. This array is replaced during a strategic\n                                                merge patch.\n                                              items:\n                                                type: string\n                                              type: array\n                                              x-kubernetes-list-type: atomic\n                                          required:\n                                          - key\n                                          - operator\n                                          type: object\n                                        type: array\n                                        x-kubernetes-list-type: atomic\n                                      matchLabels:\n                                        additionalProperties:\n                                          type: string\n                                        description: |-\n                                          matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels\n                                          map is equivalent to an element of matchExpressions, whose key field is \"key\", the\n                                          operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.\n                                        type: object\n                                    type: object\n                                    x-kubernetes-map-type: atomic\n                                  name:\n                                    description: |-\n                                      Select a single ClusterTrustBundle by object name.  Mutually-exclusive\n                                      with signerName and labelSelector.\n                                    type: string\n                                  optional:\n                                    description: |-\n                                      If true, don't block pod startup if the referenced ClusterTrustBundle(s)\n                                      aren't available.  If using name, then the named ClusterTrustBundle is\n                                      allowed not to exist.  If using signerName, then the combination of\n                                      signerName and labelSelector is allowed to match zero\n                                      ClusterTrustBundles.\n                                    type: boolean\n                                  path:\n                                    description: Relative path from the volume root to write the bundle.\n                                    type: string\n                                  signerName:\n                                    description: |-\n                                      Select all ClusterTrustBundles that match this signer name.\n                                      Mutually-exclusive with name.  The contents of all selected\n                                      ClusterTrustBundles will be unified and deduplicated.\n                                    type: string\n                                required:\n                                - path\n                                type: object\n                              configMap:\n                                description: configMap information about the configMap data to project\n                                properties:\n                                  items:\n                                    description: |-\n                                      items if unspecified, each key-value pair in the Data field of the referenced\n                                      ConfigMap will be projected into the volume as a file whose name is the\n                                      key and content is the value. If specified, the listed keys will be\n                                      projected into the specified paths, and unlisted keys will not be\n                                      present. If a key is specified which is not present in the ConfigMap,\n                                      the volume setup will error unless it is marked optional. Paths must be\n                                      relative and may not contain the '..' path or start with '..'.\n                                    items:\n                                      description: Maps a string key to a path within a volume.\n                                      properties:\n                                        key:\n                                          description: key is the key to project.\n                                          type: string\n                                        mode:\n                                          description: |-\n                                            mode is Optional: mode bits used to set permissions on this file.\n                                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                            If not specified, the volume defaultMode will be used.\n                                            This might be in conflict with other options that affect the file\n                                            mode, like fsGroup, and the result can be other mode bits set.\n                                          format: int32\n                                          type: integer\n                                        path:\n                                          description: |-\n                                            path is the relative path of the file to map the key to.\n                                            May not be an absolute path.\n                                            May not contain the path element '..'.\n                                            May not start with the string '..'.\n                                          type: string\n                                      required:\n                                      - key\n                                      - path\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: optional specify whether the ConfigMap or its keys must be defined\n                                    type: boolean\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              downwardAPI:\n                                description: downwardAPI information about the downwardAPI data to project\n                                properties:\n                                  items:\n                                    description: Items is a list of DownwardAPIVolume file\n                                    items:\n                                      description: DownwardAPIVolumeFile represents information to create the file containing the pod field\n                                      properties:\n                                        fieldRef:\n                                          description: 'Required: Selects a field of the pod: only annotations, labels, name, namespace and uid are supported.'\n                                          properties:\n                                            apiVersion:\n                                              description: Version of the schema the FieldPath is written in terms of, defaults to \"v1\".\n                                              type: string\n                                            fieldPath:\n                                              description: Path of the field to select in the specified API version.\n                                              type: string\n                                          required:\n                                          - fieldPath\n                                          type: object\n                                          x-kubernetes-map-type: atomic\n                                        mode:\n                                          description: |-\n                                            Optional: mode bits used to set permissions on this file, must be an octal value\n                                            between 0000 and 0777 or a decimal value between 0 and 511.\n                                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                            If not specified, the volume defaultMode will be used.\n                                            This might be in conflict with other options that affect the file\n                                            mode, like fsGroup, and the result can be other mode bits set.\n                                          format: int32\n                                          type: integer\n                                        path:\n                                          description: 'Required: Path is  the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..'''\n                                          type: string\n                                        resourceFieldRef:\n                                          description: |-\n                                            Selects a resource of the container: only resources limits and requests\n                                            (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.\n                                          properties:\n                                            containerName:\n                                              description: 'Container name: required for volumes, optional for env vars'\n                                              type: string\n                                            divisor:\n                                              anyOf:\n                                              - type: integer\n                                              - type: string\n                                              description: Specifies the output format of the exposed resources, defaults to \"1\"\n                                              pattern: ^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$\n                                              x-kubernetes-int-or-string: true\n                                            resource:\n                                              description: 'Required: resource to select'\n                                              type: string\n                                          required:\n                                          - resource\n                                          type: object\n                                          x-kubernetes-map-type: atomic\n                                      required:\n                                      - path\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                type: object\n                              secret:\n                                description: secret information about the secret data to project\n                                properties:\n                                  items:\n                                    description: |-\n                                      items if unspecified, each key-value pair in the Data field of the referenced\n                                      Secret will be projected into the volume as a file whose name is the\n                                      key and content is the value. If specified, the listed keys will be\n                                      projected into the specified paths, and unlisted keys will not be\n                                      present. If a key is specified which is not present in the Secret,\n                                      the volume setup will error unless it is marked optional. Paths must be\n                                      relative and may not contain the '..' path or start with '..'.\n                                    items:\n                                      description: Maps a string key to a path within a volume.\n                                      properties:\n                                        key:\n                                          description: key is the key to project.\n                                          type: string\n                                        mode:\n                                          description: |-\n                                            mode is Optional: mode bits used to set permissions on this file.\n                                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                            YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                            If not specified, the volume defaultMode will be used.\n                                            This might be in conflict with other options that affect the file\n                                            mode, like fsGroup, and the result can be other mode bits set.\n                                          format: int32\n                                          type: integer\n                                        path:\n                                          description: |-\n                                            path is the relative path of the file to map the key to.\n                                            May not be an absolute path.\n                                            May not contain the path element '..'.\n                                            May not start with the string '..'.\n                                          type: string\n                                      required:\n                                      - key\n                                      - path\n                                      type: object\n                                    type: array\n                                    x-kubernetes-list-type: atomic\n                                  name:\n                                    default: \"\"\n                                    description: |-\n                                      Name of the referent.\n                                      This field is effectively required, but due to backwards compatibility is\n                                      allowed to be empty. Instances of this type with an empty value here are\n                                      almost certainly wrong.\n                                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                    type: string\n                                  optional:\n                                    description: optional field specify whether the Secret or its key must be defined\n                                    type: boolean\n                                type: object\n                                x-kubernetes-map-type: atomic\n                              serviceAccountToken:\n                                description: serviceAccountToken is information about the serviceAccountToken data to project\n                                properties:\n                                  audience:\n                                    description: |-\n                                      audience is the intended audience of the token. A recipient of a token\n                                      must identify itself with an identifier specified in the audience of the\n                                      token, and otherwise should reject the token. The audience defaults to the\n                                      identifier of the apiserver.\n                                    type: string\n                                  expirationSeconds:\n                                    description: |-\n                                      expirationSeconds is the requested duration of validity of the service\n                                      account token. As the token approaches expiration, the kubelet volume\n                                      plugin will proactively rotate the service account token. The kubelet will\n                                      start trying to rotate the token if the token is older than 80 percent of\n                                      its time to live or if the token is older than 24 hours.Defaults to 1 hour\n                                      and must be at least 10 minutes.\n                                    format: int64\n                                    type: integer\n                                  path:\n                                    description: |-\n                                      path is the path relative to the mount point of the file to project the\n                                      token into.\n                                    type: string\n                                required:\n                                - path\n                                type: object\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                      type: object\n                    quobyte:\n                      description: |-\n                        quobyte represents a Quobyte mount on the host that shares a pod's lifetime.\n                        Deprecated: Quobyte is deprecated and the in-tree quobyte type is no longer supported.\n                      properties:\n                        group:\n                          description: |-\n                            group to map volume access to\n                            Default is no group\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the Quobyte volume to be mounted with read-only permissions.\n                            Defaults to false.\n                          type: boolean\n                        registry:\n                          description: |-\n                            registry represents a single or multiple Quobyte Registry services\n                            specified as a string as host:port pair (multiple entries are separated with commas)\n                            which acts as the central registry for volumes\n                          type: string\n                        tenant:\n                          description: |-\n                            tenant owning the given Quobyte volume in the Backend\n                            Used with dynamically provisioned Quobyte volumes, value is set by the plugin\n                          type: string\n                        user:\n                          description: |-\n                            user to map volume access to\n                            Defaults to serivceaccount user\n                          type: string\n                        volume:\n                          description: volume is a string that references an already created Quobyte volume by name.\n                          type: string\n                      required:\n                      - registry\n                      - volume\n                      type: object\n                    rbd:\n                      description: |-\n                        rbd represents a Rados Block Device mount on the host that shares a pod's lifetime.\n                        Deprecated: RBD is deprecated and the in-tree rbd type is no longer supported.\n                        More info: https://examples.k8s.io/volumes/rbd/README.md\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type of the volume that you want to mount.\n                            Tip: Ensure that the filesystem type is supported by the host operating system.\n                            Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd\n                          type: string\n                        image:\n                          description: |-\n                            image is the rados image name.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                        keyring:\n                          default: /etc/ceph/keyring\n                          description: |-\n                            keyring is the path to key ring for RBDUser.\n                            Default is /etc/ceph/keyring.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                        monitors:\n                          description: |-\n                            monitors is a collection of Ceph monitors.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          items:\n                            type: string\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        pool:\n                          default: rbd\n                          description: |-\n                            pool is the rados pool name.\n                            Default is rbd.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly here will force the ReadOnly setting in VolumeMounts.\n                            Defaults to false.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef is name of the authentication secret for RBDUser. If provided\n                            overrides keyring.\n                            Default is nil.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        user:\n                          default: admin\n                          description: |-\n                            user is the rados user name.\n                            Default is admin.\n                            More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it\n                          type: string\n                      required:\n                      - image\n                      - monitors\n                      type: object\n                    scaleIO:\n                      description: |-\n                        scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes.\n                        Deprecated: ScaleIO is deprecated and the in-tree scaleIO type is no longer supported.\n                      properties:\n                        fsType:\n                          default: xfs\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\".\n                            Default is \"xfs\".\n                          type: string\n                        gateway:\n                          description: gateway is the host address of the ScaleIO API Gateway.\n                          type: string\n                        protectionDomain:\n                          description: protectionDomain is the name of the ScaleIO Protection Domain for the configured storage.\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly Defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef references to the secret for ScaleIO user and other\n                            sensitive information. If this is not provided, Login operation will fail.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        sslEnabled:\n                          description: sslEnabled Flag enable/disable SSL communication with Gateway, default false\n                          type: boolean\n                        storageMode:\n                          default: ThinProvisioned\n                          description: |-\n                            storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned.\n                            Default is ThinProvisioned.\n                          type: string\n                        storagePool:\n                          description: storagePool is the ScaleIO Storage Pool associated with the protection domain.\n                          type: string\n                        system:\n                          description: system is the name of the storage system as configured in ScaleIO.\n                          type: string\n                        volumeName:\n                          description: |-\n                            volumeName is the name of a volume already created in the ScaleIO system\n                            that is associated with this volume source.\n                          type: string\n                      required:\n                      - gateway\n                      - secretRef\n                      - system\n                      type: object\n                    secret:\n                      description: |-\n                        secret represents a secret that should populate this volume.\n                        More info: https://kubernetes.io/docs/concepts/storage/volumes#secret\n                      properties:\n                        defaultMode:\n                          description: |-\n                            defaultMode is Optional: mode bits used to set permissions on created files by default.\n                            Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                            YAML accepts both octal and decimal values, JSON requires decimal values\n                            for mode bits. Defaults to 0644.\n                            Directories within the path are not affected by this setting.\n                            This might be in conflict with other options that affect the file\n                            mode, like fsGroup, and the result can be other mode bits set.\n                          format: int32\n                          type: integer\n                        items:\n                          description: |-\n                            items If unspecified, each key-value pair in the Data field of the referenced\n                            Secret will be projected into the volume as a file whose name is the\n                            key and content is the value. If specified, the listed keys will be\n                            projected into the specified paths, and unlisted keys will not be\n                            present. If a key is specified which is not present in the Secret,\n                            the volume setup will error unless it is marked optional. Paths must be\n                            relative and may not contain the '..' path or start with '..'.\n                          items:\n                            description: Maps a string key to a path within a volume.\n                            properties:\n                              key:\n                                description: key is the key to project.\n                                type: string\n                              mode:\n                                description: |-\n                                  mode is Optional: mode bits used to set permissions on this file.\n                                  Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511.\n                                  YAML accepts both octal and decimal values, JSON requires decimal values for mode bits.\n                                  If not specified, the volume defaultMode will be used.\n                                  This might be in conflict with other options that affect the file\n                                  mode, like fsGroup, and the result can be other mode bits set.\n                                format: int32\n                                type: integer\n                              path:\n                                description: |-\n                                  path is the relative path of the file to map the key to.\n                                  May not be an absolute path.\n                                  May not contain the path element '..'.\n                                  May not start with the string '..'.\n                                type: string\n                            required:\n                            - key\n                            - path\n                            type: object\n                          type: array\n                          x-kubernetes-list-type: atomic\n                        optional:\n                          description: optional field specify whether the Secret or its keys must be defined\n                          type: boolean\n                        secretName:\n                          description: |-\n                            secretName is the name of the secret in the pod's namespace to use.\n                            More info: https://kubernetes.io/docs/concepts/storage/volumes#secret\n                          type: string\n                      type: object\n                    storageos:\n                      description: |-\n                        storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes.\n                        Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is the filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        readOnly:\n                          description: |-\n                            readOnly defaults to false (read/write). ReadOnly here will force\n                            the ReadOnly setting in VolumeMounts.\n                          type: boolean\n                        secretRef:\n                          description: |-\n                            secretRef specifies the secret to use for obtaining the StorageOS API\n                            credentials.  If not specified, default values will be attempted.\n                          properties:\n                            name:\n                              default: \"\"\n                              description: |-\n                                Name of the referent.\n                                This field is effectively required, but due to backwards compatibility is\n                                allowed to be empty. Instances of this type with an empty value here are\n                                almost certainly wrong.\n                                More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                              type: string\n                          type: object\n                          x-kubernetes-map-type: atomic\n                        volumeName:\n                          description: |-\n                            volumeName is the human-readable name of the StorageOS volume.  Volume\n                            names are only unique within a namespace.\n                          type: string\n                        volumeNamespace:\n                          description: |-\n                            volumeNamespace specifies the scope of the volume within StorageOS.  If no\n                            namespace is specified then the Pod's namespace will be used.  This allows the\n                            Kubernetes name scoping to be mirrored within StorageOS for tighter integration.\n                            Set VolumeName to any name to override the default behaviour.\n                            Set to \"default\" if you are not using namespaces within StorageOS.\n                            Namespaces that do not pre-exist within StorageOS will be created.\n                          type: string\n                      type: object\n                    vsphereVolume:\n                      description: |-\n                        vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine.\n                        Deprecated: VsphereVolume is deprecated. All operations for the in-tree vsphereVolume type\n                        are redirected to the csi.vsphere.vmware.com CSI driver.\n                      properties:\n                        fsType:\n                          description: |-\n                            fsType is filesystem type to mount.\n                            Must be a filesystem type supported by the host operating system.\n                            Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.\n                          type: string\n                        storagePolicyID:\n                          description: storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName.\n                          type: string\n                        storagePolicyName:\n                          description: storagePolicyName is the storage Policy Based Management (SPBM) profile name.\n                          type: string\n                        volumePath:\n                          description: volumePath is the path that identifies vSphere volume vmdk\n                          type: string\n                      required:\n                      - volumePath\n                      type: object\n                  required:\n                  - name\n                  type: object\n                type: array\n              web:\n                description: Defines the configuration of the ThanosRuler web server.\n                properties:\n                  httpConfig:\n                    description: Defines HTTP parameters for web server.\n                    properties:\n                      headers:\n                        description: List of headers that can be added to HTTP responses.\n                        properties:\n                          contentSecurityPolicy:\n                            description: |-\n                              Set the Content-Security-Policy header to HTTP responses.\n                              Unset if blank.\n                            type: string\n                          strictTransportSecurity:\n                            description: |-\n                              Set the Strict-Transport-Security header to HTTP responses.\n                              Unset if blank.\n                              Please make sure that you use this with care as this header might force\n                              browsers to load Prometheus and the other applications hosted on the same\n                              domain and subdomains over HTTPS.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security\n                            type: string\n                          xContentTypeOptions:\n                            description: |-\n                              Set the X-Content-Type-Options header to HTTP responses.\n                              Unset if blank. Accepted value is nosniff.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n                            enum:\n                            - \"\"\n                            - NoSniff\n                            type: string\n                          xFrameOptions:\n                            description: |-\n                              Set the X-Frame-Options header to HTTP responses.\n                              Unset if blank. Accepted values are deny and sameorigin.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n                            enum:\n                            - \"\"\n                            - Deny\n                            - SameOrigin\n                            type: string\n                          xXSSProtection:\n                            description: |-\n                              Set the X-XSS-Protection header to all responses.\n                              Unset if blank.\n                              https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n                            type: string\n                        type: object\n                      http2:\n                        description: |-\n                          Enable HTTP/2 support. Note that HTTP/2 is only supported with TLS.\n                          When TLSConfig is not configured, HTTP/2 will be disabled.\n                          Whenever the value of the field changes, a rolling update will be triggered.\n                        type: boolean\n                    type: object\n                  tlsConfig:\n                    description: Defines the TLS parameters for HTTPS.\n                    properties:\n                      cert:\n                        description: |-\n                          Secret or ConfigMap containing the TLS certificate for the web server.\n\n                          Either `keySecret` or `keyFile` must be defined.\n\n                          It is mutually exclusive with `certFile`.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      certFile:\n                        description: |-\n                          Path to the TLS certificate file in the container for the web server.\n\n                          Either `keySecret` or `keyFile` must be defined.\n\n                          It is mutually exclusive with `cert`.\n                        type: string\n                      cipherSuites:\n                        description: |-\n                          List of supported cipher suites for TLS versions up to TLS 1.2.\n\n                          If not defined, the Go default cipher suites are used.\n                          Available cipher suites are documented in the Go documentation:\n                          https://golang.org/pkg/crypto/tls/#pkg-constants\n                        items:\n                          type: string\n                        type: array\n                      client_ca:\n                        description: |-\n                          Secret or ConfigMap containing the CA certificate for client certificate\n                          authentication to the server.\n\n                          It is mutually exclusive with `clientCAFile`.\n                        properties:\n                          configMap:\n                            description: ConfigMap containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key to select.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the ConfigMap or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                          secret:\n                            description: Secret containing data to use for the targets.\n                            properties:\n                              key:\n                                description: The key of the secret to select from.  Must be a valid secret key.\n                                type: string\n                              name:\n                                default: \"\"\n                                description: |-\n                                  Name of the referent.\n                                  This field is effectively required, but due to backwards compatibility is\n                                  allowed to be empty. Instances of this type with an empty value here are\n                                  almost certainly wrong.\n                                  More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                                type: string\n                              optional:\n                                description: Specify whether the Secret or its key must be defined\n                                type: boolean\n                            required:\n                            - key\n                            type: object\n                            x-kubernetes-map-type: atomic\n                        type: object\n                      clientAuthType:\n                        description: |-\n                          The server policy for client TLS authentication.\n\n                          For more detail on clientAuth options:\n                          https://golang.org/pkg/crypto/tls/#ClientAuthType\n                        type: string\n                      clientCAFile:\n                        description: |-\n                          Path to the CA certificate file for client certificate authentication to\n                          the server.\n\n                          It is mutually exclusive with `client_ca`.\n                        type: string\n                      curvePreferences:\n                        description: |-\n                          Elliptic curves that will be used in an ECDHE handshake, in preference\n                          order.\n\n                          Available curves are documented in the Go documentation:\n                          https://golang.org/pkg/crypto/tls/#CurveID\n                        items:\n                          type: string\n                        type: array\n                      keyFile:\n                        description: |-\n                          Path to the TLS private key file in the container for the web server.\n\n                          If defined, either `cert` or `certFile` must be defined.\n\n                          It is mutually exclusive with `keySecret`.\n                        type: string\n                      keySecret:\n                        description: |-\n                          Secret containing the TLS private key for the web server.\n\n                          Either `cert` or `certFile` must be defined.\n\n                          It is mutually exclusive with `keyFile`.\n                        properties:\n                          key:\n                            description: The key of the secret to select from.  Must be a valid secret key.\n                            type: string\n                          name:\n                            default: \"\"\n                            description: |-\n                              Name of the referent.\n                              This field is effectively required, but due to backwards compatibility is\n                              allowed to be empty. Instances of this type with an empty value here are\n                              almost certainly wrong.\n                              More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\n                            type: string\n                          optional:\n                            description: Specify whether the Secret or its key must be defined\n                            type: boolean\n                        required:\n                        - key\n                        type: object\n                        x-kubernetes-map-type: atomic\n                      maxVersion:\n                        description: Maximum TLS version that is acceptable.\n                        type: string\n                      minVersion:\n                        description: Minimum TLS version that is acceptable.\n                        type: string\n                      preferServerCipherSuites:\n                        description: |-\n                          Controls whether the server selects the client's most preferred cipher\n                          suite, or the server's most preferred cipher suite.\n\n                          If true then the server's preference, as expressed in\n                          the order of elements in cipherSuites, is used.\n                        type: boolean\n                    type: object\n                type: object\n            type: object\n          status:\n            description: |-\n              Most recent observed status of the ThanosRuler cluster. Read-only.\n              More info:\n              https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status\n            properties:\n              availableReplicas:\n                description: |-\n                  Total number of available pods (ready for at least minReadySeconds)\n                  targeted by this ThanosRuler deployment.\n                format: int32\n                type: integer\n              conditions:\n                description: The current state of the ThanosRuler object.\n                items:\n                  description: |-\n                    Condition represents the state of the resources associated with the\n                    Prometheus, Alertmanager or ThanosRuler resource.\n                  properties:\n                    lastTransitionTime:\n                      description: lastTransitionTime is the time of the last update to the current status property.\n                      format: date-time\n                      type: string\n                    message:\n                      description: Human-readable message indicating details for the condition's last transition.\n                      type: string\n                    observedGeneration:\n                      description: |-\n                        ObservedGeneration represents the .metadata.generation that the\n                        condition was set based upon. For instance, if `.metadata.generation` is\n                        currently 12, but the `.status.conditions[].observedGeneration` is 9, the\n                        condition is out of date with respect to the current state of the\n                        instance.\n                      format: int64\n                      type: integer\n                    reason:\n                      description: Reason for the condition's last transition.\n                      type: string\n                    status:\n                      description: Status of the condition.\n                      minLength: 1\n                      type: string\n                    type:\n                      description: Type of the condition being reported.\n                      minLength: 1\n                      type: string\n                  required:\n                  - lastTransitionTime\n                  - status\n                  - type\n                  type: object\n                type: array\n                x-kubernetes-list-map-keys:\n                - type\n                x-kubernetes-list-type: map\n              paused:\n                description: |-\n                  Represents whether any actions on the underlying managed objects are\n                  being performed. Only delete actions will be performed.\n                type: boolean\n              replicas:\n                description: |-\n                  Total number of non-terminated pods targeted by this ThanosRuler deployment\n                  (their labels match the selector).\n                format: int32\n                type: integer\n              unavailableReplicas:\n                description: Total number of unavailable pods targeted by this ThanosRuler deployment.\n                format: int32\n                type: integer\n              updatedReplicas:\n                description: |-\n                  Total number of non-terminated pods targeted by this ThanosRuler deployment\n                  that have the desired version spec.\n                format: int32\n                type: integer\n            required:\n            - availableReplicas\n            - paused\n            - replicas\n            - unavailableReplicas\n            - updatedReplicas\n            type: object\n        required:\n        - spec\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n"
  },
  {
    "path": "hack/config/monitoring/crds/README.md",
    "content": "The CRDs in this directory were downloaded from\nhttps://github.com/prometheus-operator/kube-prometheus/tree/v0.16.0/manifests/setup.\n\nBump the version in [`update.sh`](../update.sh) and run the script to update the CRDs.\n"
  },
  {
    "path": "hack/config/monitoring/crds/kustomization.yaml",
    "content": "# Code generated by update.sh, DO NOT EDIT.\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nlabels:\n- includeSelectors: true\n  pairs:\n    app.kubernetes.io/name: prometheus-operator\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.85.0\n\nresources:\n- 0alertmanagerConfigCustomResourceDefinition.yaml\n- 0alertmanagerCustomResourceDefinition.yaml\n- 0podmonitorCustomResourceDefinition.yaml\n- 0probeCustomResourceDefinition.yaml\n- 0prometheusagentCustomResourceDefinition.yaml\n- 0prometheusCustomResourceDefinition.yaml\n- 0prometheusruleCustomResourceDefinition.yaml\n- 0scrapeconfigCustomResourceDefinition.yaml\n- 0servicemonitorCustomResourceDefinition.yaml\n- 0thanosrulerCustomResourceDefinition.yaml\n"
  },
  {
    "path": "hack/config/monitoring/default/dashboards/client-go.json",
    "content": "{\n  \"annotations\": {\n    \"list\": [\n      {\n        \"builtIn\": 1,\n        \"datasource\": {\n          \"type\": \"grafana\",\n          \"uid\": \"-- Grafana --\"\n        },\n        \"enable\": true,\n        \"hide\": true,\n        \"iconColor\": \"rgba(0, 211, 255, 1)\",\n        \"name\": \"Annotations & Alerts\",\n        \"target\": {\n          \"limit\": 100,\n          \"matchAny\": false,\n          \"tags\": [],\n          \"type\": \"dashboard\"\n        },\n        \"type\": \"dashboard\"\n      }\n    ]\n  },\n  \"editable\": true,\n  \"fiscalYearStartMonth\": 0,\n  \"graphTooltip\": 0,\n  \"links\": [],\n  \"liveNow\": false,\n  \"panels\": [\n    {\n      \"collapsed\": false,\n      \"datasource\": {\n        \"type\": \"datasource\",\n        \"uid\": \"grafana\"\n      },\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 0\n      },\n      \"id\": 9,\n      \"panels\": [],\n      \"title\": \"Request Rate\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\",\n            \"seriesBy\": \"min\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 1\n      },\n      \"id\": 7,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(rest_client_requests_total{job=\\\"$job\\\",pod=~\\\"$pod\\\",method=~\\\"$verb\\\",code=~\\\"$code\\\"}[$__rate_interval])) by (pod)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Request Rate by pod\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"error\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"red\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"success\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"green\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"requeue\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"orange\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"requeue_after\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"blue\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 1\n      },\n      \"id\": 21,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(rest_client_requests_total{job=\\\"$job\\\",pod=~\\\"$pod\\\",method=~\\\"$verb\\\",code=~\\\"$code\\\"}[$__rate_interval])) by (code)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{result}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Request Rate by code\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"error\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"red\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"success\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"green\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"requeue\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"orange\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"requeue_after\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"blue\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 10\n      },\n      \"id\": 36,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(rest_client_requests_total{job=\\\"$job\\\",pod=~\\\"$pod\\\",method=~\\\"$verb\\\",code=~\\\"$code\\\"}[$__rate_interval])) by (method)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{result}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Request Rate by verb\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 19\n      },\n      \"id\": 32,\n      \"panels\": [],\n      \"title\": \"Request / Response Sizes\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"decbytes\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 20\n      },\n      \"id\": 23,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile($percentile/100, sum(rate(rest_client_request_size_bytes_bucket{job=\\\"$job\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod,le))\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Request Size by pod (P$percentile)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"decbytes\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 20\n      },\n      \"id\": 37,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile($percentile/100, sum(rate(rest_client_request_size_bytes_bucket{job=\\\"$job\\\",pod=~\\\"$pod\\\",verb=~\\\"$verb\\\"}[$__rate_interval])) by (verb,le))\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{verb}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Request Size by verb (P$percentile)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"decbytes\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 29\n      },\n      \"id\": 38,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile($percentile/100, sum(rate(rest_client_response_size_bytes_bucket{job=\\\"$job\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod,le))\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Response Size by pod (P$percentile)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"decbytes\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 29\n      },\n      \"id\": 39,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile($percentile/100, sum(rate(rest_client_response_size_bytes_bucket{job=\\\"$job\\\",pod=~\\\"$pod\\\",verb=~\\\"$verb\\\"}[$__rate_interval])) by (verb,le))\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{verb}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Response Size by verb (P$percentile)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 38\n      },\n      \"id\": 41,\n      \"panels\": [],\n      \"title\": \"Rate Limiter\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 39\n      },\n      \"id\": 42,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile($percentile/100, sum(rate(rest_client_rate_limiter_duration_seconds_bucket{job=\\\"$job\\\",pod=~\\\"$pod\\\",verb=~\\\"$verb\\\"}[$__rate_interval])) by (pod,le))\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Rate Limiter Duration by pod (P$percentile)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 39\n      },\n      \"id\": 43,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile($percentile/100, sum(rate(rest_client_rate_limiter_duration_seconds_bucket{job=\\\"$job\\\",pod=~\\\"$pod\\\",verb=~\\\"$verb\\\"}[$__rate_interval])) by (verb,le))\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{verb}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Rate Limiter Duration by verb (P$percentile)\",\n      \"type\": \"timeseries\"\n    }\n  ],\n  \"refresh\": \"10s\",\n  \"schemaVersion\": 38,\n  \"style\": \"dark\",\n  \"tags\": [\n    \"controller-runtime\"\n  ],\n  \"templating\": {\n    \"list\": [\n      {\n        \"current\": {\n          \"selected\": false,\n          \"text\": \"prometheus\",\n          \"value\": \"prometheus\"\n        },\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"multi\": false,\n        \"name\": \"datasource\",\n        \"options\": [],\n        \"query\": \"prometheus\",\n        \"queryValue\": \"\",\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"type\": \"datasource\"\n      },\n      {\n        \"allFormat\": \"glob\",\n        \"current\": {\n          \"selected\": false,\n          \"text\": \"webhosting-operator\",\n          \"value\": \"webhosting-operator\"\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(controller_runtime_reconcile_total{}, job)\",\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"multi\": false,\n        \"name\": \"job\",\n        \"options\": [],\n        \"query\": {\n          \"query\": \"label_values(controller_runtime_reconcile_total{}, job)\",\n          \"refId\": \"StandardVariableQuery\"\n        },\n        \"refresh\": 2,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"allFormat\": \"glob\",\n        \"allValue\": \".*\",\n        \"current\": {\n          \"selected\": true,\n          \"text\": [\n            \"All\"\n          ],\n          \"value\": [\n            \"$__all\"\n          ]\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(controller_runtime_reconcile_total{job=\\\"$job\\\"}, pod)\",\n        \"hide\": 0,\n        \"includeAll\": true,\n        \"multi\": true,\n        \"name\": \"pod\",\n        \"options\": [],\n        \"query\": {\n          \"query\": \"label_values(controller_runtime_reconcile_total{job=\\\"$job\\\"}, pod)\",\n          \"refId\": \"StandardVariableQuery\"\n        },\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"allFormat\": \"glob\",\n        \"allValue\": \".*\",\n        \"current\": {\n          \"selected\": true,\n          \"text\": [\n            \"All\"\n          ],\n          \"value\": [\n            \"$__all\"\n          ]\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(rest_client_requests_total{job=\\\"$job\\\"}, method)\",\n        \"hide\": 0,\n        \"includeAll\": true,\n        \"multi\": true,\n        \"name\": \"verb\",\n        \"options\": [],\n        \"query\": {\n          \"query\": \"label_values(rest_client_requests_total{job=\\\"$job\\\"}, method)\",\n          \"refId\": \"StandardVariableQuery\"\n        },\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"allFormat\": \"glob\",\n        \"allValue\": \".*\",\n        \"current\": {\n          \"selected\": true,\n          \"text\": [\n            \"All\"\n          ],\n          \"value\": [\n            \"$__all\"\n          ]\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(rest_client_requests_total{job=\\\"$job\\\"}, code)\",\n        \"hide\": 0,\n        \"includeAll\": true,\n        \"multi\": true,\n        \"name\": \"code\",\n        \"options\": [],\n        \"query\": {\n          \"query\": \"label_values(rest_client_requests_total{job=\\\"$job\\\"}, code)\",\n          \"refId\": \"StandardVariableQuery\"\n        },\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"current\": {\n          \"selected\": true,\n          \"text\": \"99\",\n          \"value\": \"99\"\n        },\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"multi\": false,\n        \"name\": \"percentile\",\n        \"options\": [\n          {\n            \"selected\": false,\n            \"text\": \"90\",\n            \"value\": \"90\"\n          },\n          {\n            \"selected\": false,\n            \"text\": \"95\",\n            \"value\": \"95\"\n          },\n          {\n            \"selected\": true,\n            \"text\": \"99\",\n            \"value\": \"99\"\n          }\n        ],\n        \"query\": \"90,95,99\",\n        \"queryValue\": \"\",\n        \"skipUrlSync\": false,\n        \"type\": \"custom\"\n      }\n    ]\n  },\n  \"time\": {\n    \"from\": \"now-1h\",\n    \"to\": \"now\"\n  },\n  \"timepicker\": {},\n  \"timezone\": \"\",\n  \"title\": \"Controller Runtime / Client-Go\",\n  \"uid\": \"qIJCg2S4z\",\n  \"version\": 1,\n  \"weekStart\": \"\"\n}\n"
  },
  {
    "path": "hack/config/monitoring/default/dashboards/controller-details.json",
    "content": "{\n  \"annotations\": {\n    \"list\": [\n      {\n        \"builtIn\": 1,\n        \"datasource\": {\n          \"type\": \"grafana\",\n          \"uid\": \"-- Grafana --\"\n        },\n        \"enable\": true,\n        \"hide\": true,\n        \"iconColor\": \"rgba(0, 211, 255, 1)\",\n        \"name\": \"Annotations & Alerts\",\n        \"target\": {\n          \"limit\": 100,\n          \"matchAny\": false,\n          \"tags\": [],\n          \"type\": \"dashboard\"\n        },\n        \"type\": \"dashboard\"\n      }\n    ]\n  },\n  \"editable\": true,\n  \"fiscalYearStartMonth\": 0,\n  \"graphTooltip\": 0,\n  \"links\": [],\n  \"liveNow\": false,\n  \"panels\": [\n    {\n      \"collapsed\": false,\n      \"datasource\": {\n        \"type\": \"datasource\",\n        \"uid\": \"grafana\"\n      },\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 0\n      },\n      \"id\": 9,\n      \"panels\": [],\n      \"title\": \"Reconciliations\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\",\n            \"seriesBy\": \"min\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 1\n      },\n      \"id\": 7,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(controller_runtime_reconcile_total{job=\\\"$job\\\",controller=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Reconciliation Rate by pod\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"error\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"red\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"success\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"green\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"requeue\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"orange\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"requeue_after\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"blue\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 1\n      },\n      \"id\": 21,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(controller_runtime_reconcile_total{job=\\\"$job\\\",controller=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (result)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{result}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Reconciliation Rate by result\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"continuous-GrYlRd\",\n            \"seriesBy\": \"last\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 10,\n            \"gradientMode\": \"scheme\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 10\n      },\n      \"id\": 20,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(controller_runtime_reconcile_errors_total{job=\\\"$job\\\",controller=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Error Rate by pod\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 10\n      },\n      \"id\": 23,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile(0.9, sum(rate(controller_runtime_reconcile_time_seconds_bucket{job=\\\"$job\\\",controller=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (controller,le))\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"P90\",\n          \"range\": true,\n          \"refId\": \"A\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile(0.95, sum(rate(controller_runtime_reconcile_time_seconds_bucket{job=\\\"$job\\\",controller=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (controller,le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"P95\",\n          \"range\": true,\n          \"refId\": \"B\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile(0.99, sum(rate(controller_runtime_reconcile_time_seconds_bucket{job=\\\"$job\\\",controller=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (controller,le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"P99\",\n          \"range\": true,\n          \"refId\": \"C\"\n        }\n      ],\n      \"title\": \"Reconciliation Time (P90, P95, P99)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 19\n      },\n      \"id\": 32,\n      \"panels\": [],\n      \"title\": \"Workers\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"none\"\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Max\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"red\",\n                  \"mode\": \"fixed\"\n                }\n              },\n              {\n                \"id\": \"custom.gradientMode\",\n                \"value\": \"none\"\n              },\n              {\n                \"id\": \"custom.fillOpacity\",\n                \"value\": 0\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 20\n      },\n      \"id\": 22,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(controller_runtime_active_workers{job=\\\"$job\\\",controller=~\\\"$controller\\\",pod=~\\\"$pod\\\"}) by (pod)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"max(controller_runtime_max_concurrent_reconciles{job=\\\"$job\\\",controller=~\\\"$controller\\\",pod=~\\\"$pod\\\"})\",\n          \"hide\": false,\n          \"legendFormat\": \"Max\",\n          \"range\": true,\n          \"refId\": \"B\"\n        }\n      ],\n      \"title\": \"Active Workers by pod\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"continuous-RdYlGr\"\n          },\n          \"custom\": {\n            \"align\": \"auto\",\n            \"cellOptions\": {\n              \"type\": \"auto\"\n            },\n            \"inspect\": false\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          },\n          \"unit\": \"none\"\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Value\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"custom.cellOptions\",\n                \"value\": {\n                  \"mode\": \"gradient\",\n                  \"type\": \"color-background\"\n                }\n              },\n              {\n                \"id\": \"custom.width\",\n                \"value\": 80\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 20\n      },\n      \"id\": 35,\n      \"options\": {\n        \"cellHeight\": \"sm\",\n        \"footer\": {\n          \"countRows\": false,\n          \"fields\": \"\",\n          \"reducer\": [\n            \"sum\"\n          ],\n          \"show\": false\n        },\n        \"showHeader\": true,\n        \"sortBy\": []\n      },\n      \"pluginVersion\": \"9.5.3\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(controller_runtime_max_concurrent_reconciles{job=\\\"$job\\\",controller=~\\\"$controller\\\",pod=~\\\"$pod\\\"}) by (pod)\",\n          \"format\": \"table\",\n          \"hide\": false,\n          \"instant\": true,\n          \"range\": false,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Total Workers by pod\",\n      \"transformations\": [\n        {\n          \"id\": \"organize\",\n          \"options\": {\n            \"excludeByName\": {\n              \"Time\": true\n            },\n            \"indexByName\": {},\n            \"renameByName\": {}\n          }\n        }\n      ],\n      \"type\": \"table\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"Rate of unfinished work per second not observed in work duration metrics. A constant value of 1 could indicate 1 stuck worker routine.\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"area\"\n            }\n          },\n          \"mappings\": [],\n          \"max\": 2,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 1\n              }\n            ]\n          },\n          \"unit\": \"none\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 29\n      },\n      \"id\": 29,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(rate(workqueue_unfinished_work_seconds{job=\\\"$job\\\",name=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Unfinished Work by pod\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"continuous-GrYlRd\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"scheme\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 29\n      },\n      \"id\": 30,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"max(workqueue_longest_running_processor_seconds{job=\\\"$job\\\",name=~\\\"$controller\\\",pod=~\\\"$pod\\\"}) by (pod)\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Longest Running Worker by pod\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"datasource\": {\n        \"type\": \"datasource\",\n        \"uid\": \"grafana\"\n      },\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 38\n      },\n      \"id\": 11,\n      \"panels\": [],\n      \"title\": \"Work Queue\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 39\n      },\n      \"id\": 27,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(rate(workqueue_adds_total{job=\\\"$job\\\",name=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Queue Add Rate by pod\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 39\n      },\n      \"id\": 33,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(rate(workqueue_retries_total{job=\\\"$job\\\",name=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Retry Rate by pod\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 48\n      },\n      \"id\": 24,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile(0.9, sum(rate(workqueue_queue_duration_seconds_bucket{job=\\\"$job\\\",name=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (name,le))\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"P90\",\n          \"range\": true,\n          \"refId\": \"A\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile(0.95, sum(rate(workqueue_queue_duration_seconds_bucket{job=\\\"$job\\\",name=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (name,le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"P95\",\n          \"range\": true,\n          \"refId\": \"B\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{job=\\\"$job\\\",name=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (name,le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"P99\",\n          \"range\": true,\n          \"refId\": \"C\"\n        }\n      ],\n      \"title\": \"Queue Duration (P90, P95, P99)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 48\n      },\n      \"id\": 28,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile(0.9, sum(rate(workqueue_work_duration_seconds_bucket{job=\\\"$job\\\",name=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (name,le))\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"P90\",\n          \"range\": true,\n          \"refId\": \"A\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile(0.95, sum(rate(workqueue_work_duration_seconds_bucket{job=\\\"$job\\\",name=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (name,le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"P95\",\n          \"range\": true,\n          \"refId\": \"B\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile(0.99, sum(rate(workqueue_work_duration_seconds_bucket{job=\\\"$job\\\",name=~\\\"$controller\\\",pod=~\\\"$pod\\\"}[$__rate_interval])) by (name,le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"P99\",\n          \"range\": true,\n          \"refId\": \"C\"\n        }\n      ],\n      \"title\": \"Work Duration (P90, P95, P99)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"none\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 57\n      },\n      \"id\": 25,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(workqueue_depth{job=\\\"$job\\\",name=~\\\"$controller\\\",pod=~\\\"$pod\\\"}) by (pod)\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Queue Length by pod\",\n      \"type\": \"timeseries\"\n    }\n  ],\n  \"refresh\": \"10s\",\n  \"schemaVersion\": 38,\n  \"style\": \"dark\",\n  \"tags\": [\n    \"controller-runtime\"\n  ],\n  \"templating\": {\n    \"list\": [\n      {\n        \"current\": {\n          \"selected\": false,\n          \"text\": \"prometheus\",\n          \"value\": \"prometheus\"\n        },\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"multi\": false,\n        \"name\": \"datasource\",\n        \"options\": [],\n        \"query\": \"prometheus\",\n        \"queryValue\": \"\",\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"type\": \"datasource\"\n      },\n      {\n        \"allFormat\": \"glob\",\n        \"current\": {\n          \"selected\": false,\n          \"text\": \"webhosting-operator\",\n          \"value\": \"webhosting-operator\"\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(controller_runtime_reconcile_total{}, job)\",\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"multi\": false,\n        \"name\": \"job\",\n        \"options\": [],\n        \"query\": {\n          \"query\": \"label_values(controller_runtime_reconcile_total{}, job)\",\n          \"refId\": \"StandardVariableQuery\"\n        },\n        \"refresh\": 2,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"allFormat\": \"glob\",\n        \"allValue\": \".*\",\n        \"current\": {\n          \"selected\": true,\n          \"text\": [\n            \"All\"\n          ],\n          \"value\": [\n            \"$__all\"\n          ]\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(controller_runtime_reconcile_total{job=\\\"$job\\\"}, pod)\",\n        \"hide\": 0,\n        \"includeAll\": true,\n        \"multi\": true,\n        \"name\": \"pod\",\n        \"options\": [],\n        \"query\": {\n          \"query\": \"label_values(controller_runtime_reconcile_total{job=\\\"$job\\\"}, pod)\",\n          \"refId\": \"StandardVariableQuery\"\n        },\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"allFormat\": \"glob\",\n        \"current\": {\n          \"selected\": false,\n          \"text\": \"website\",\n          \"value\": \"website\"\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(controller_runtime_reconcile_total{job=\\\"$job\\\"}, controller)\",\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"multi\": false,\n        \"name\": \"controller\",\n        \"options\": [],\n        \"query\": {\n          \"query\": \"label_values(controller_runtime_reconcile_total{job=\\\"$job\\\"}, controller)\",\n          \"refId\": \"StandardVariableQuery\"\n        },\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"sort\": 1,\n        \"type\": \"query\"\n      }\n    ]\n  },\n  \"time\": {\n    \"from\": \"now-1h\",\n    \"to\": \"now\"\n  },\n  \"timepicker\": {},\n  \"timezone\": \"\",\n  \"title\": \"Controller Runtime / Controllers / Controller Details\",\n  \"uid\": \"OjCZokmVz\",\n  \"version\": 1,\n  \"weekStart\": \"\"\n}\n"
  },
  {
    "path": "hack/config/monitoring/default/dashboards/controller-runtime.json",
    "content": "{\n  \"annotations\": {\n    \"list\": [\n      {\n        \"builtIn\": 1,\n        \"datasource\": {\n          \"type\": \"grafana\",\n          \"uid\": \"-- Grafana --\"\n        },\n        \"enable\": true,\n        \"hide\": true,\n        \"iconColor\": \"rgba(0, 211, 255, 1)\",\n        \"name\": \"Annotations & Alerts\",\n        \"target\": {\n          \"limit\": 100,\n          \"matchAny\": false,\n          \"tags\": [],\n          \"type\": \"dashboard\"\n        },\n        \"type\": \"dashboard\"\n      }\n    ]\n  },\n  \"editable\": true,\n  \"fiscalYearStartMonth\": 0,\n  \"graphTooltip\": 0,\n  \"links\": [],\n  \"liveNow\": false,\n  \"panels\": [\n    {\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 0\n      },\n      \"id\": 35,\n      \"title\": \"Headlines (over time range)\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 7,\n        \"w\": 9,\n        \"x\": 0,\n        \"y\": 1\n      },\n      \"id\": 39,\n      \"options\": {\n        \"displayMode\": \"gradient\",\n        \"minVizHeight\": 10,\n        \"minVizWidth\": 0,\n        \"orientation\": \"horizontal\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"lastNotNull\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"showUnfilled\": true,\n        \"valueMode\": \"color\"\n      },\n      \"pluginVersion\": \"9.5.3\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(rate(controller_runtime_reconcile_total{job=\\\"$job\\\",pod=~\\\"$pod\\\",controller=~\\\"$controller\\\"}[$__range])) by (controller)\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n          \"instant\": true,\n          \"legendFormat\": \"__auto\",\n          \"range\": false,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Reconciliation Rate\",\n      \"transformations\": [],\n      \"type\": \"bargauge\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"continuous-RdYlGr\"\n          },\n          \"custom\": {\n            \"align\": \"auto\",\n            \"cellOptions\": {\n              \"type\": \"auto\"\n            },\n            \"inspect\": false\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          },\n          \"unit\": \"none\"\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Value\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"custom.cellOptions\",\n                \"value\": {\n                  \"mode\": \"gradient\",\n                  \"type\": \"color-background\"\n                }\n              },\n              {\n                \"id\": \"custom.width\",\n                \"value\": 80\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"controller\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"links\",\n                \"value\": [\n                  {\n                    \"title\": \"\",\n                    \"url\": \"/d/OjCZokmVz/controller-runtime-controllers-controller-details?var-datasource=$datasource&var-job=$job&var-controller=${__data.fields.controller}\"\n                  }\n                ]\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 7,\n        \"w\": 6,\n        \"x\": 9,\n        \"y\": 1\n      },\n      \"id\": 40,\n      \"options\": {\n        \"cellHeight\": \"sm\",\n        \"footer\": {\n          \"countRows\": false,\n          \"fields\": \"\",\n          \"reducer\": [\n            \"sum\"\n          ],\n          \"show\": false\n        },\n        \"showHeader\": true,\n        \"sortBy\": [\n          {\n            \"desc\": true,\n            \"displayName\": \"Value\"\n          }\n        ]\n      },\n      \"pluginVersion\": \"9.5.3\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(controller_runtime_max_concurrent_reconciles{job=\\\"$job\\\",pod=~\\\"$pod\\\",controller=~\\\"$controller\\\"}) by (controller)\",\n          \"format\": \"table\",\n          \"hide\": false,\n          \"instant\": true,\n          \"range\": false,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Total Workers by controller\",\n      \"transformations\": [\n        {\n          \"id\": \"organize\",\n          \"options\": {\n            \"excludeByName\": {\n              \"Time\": true\n            },\n            \"indexByName\": {},\n            \"renameByName\": {}\n          }\n        }\n      ],\n      \"type\": \"table\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            }\n          },\n          \"mappings\": [],\n          \"unit\": \"s/s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 7,\n        \"w\": 9,\n        \"x\": 15,\n        \"y\": 1\n      },\n      \"id\": 38,\n      \"options\": {\n        \"displayLabels\": [],\n        \"legend\": {\n          \"displayMode\": \"table\",\n          \"placement\": \"right\",\n          \"showLegend\": true,\n          \"values\": [\n            \"percent\"\n          ]\n        },\n        \"pieType\": \"donut\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"lastNotNull\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"pluginVersion\": \"8.5.5\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(rate(controller_runtime_reconcile_time_seconds_sum{job=\\\"$job\\\",pod=~\\\"$pod\\\",controller=~\\\"$controller\\\"}[$__range])) by (controller)\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n          \"instant\": true,\n          \"legendFormat\": \"__auto\",\n          \"range\": false,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Reconciliation Time Distribution\",\n      \"transformations\": [],\n      \"type\": \"piechart\"\n    },\n    {\n      \"collapsed\": false,\n      \"datasource\": {\n        \"type\": \"datasource\",\n        \"uid\": \"grafana\"\n      },\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 8\n      },\n      \"id\": 9,\n      \"panels\": [],\n      \"title\": \"Reconciliations\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\",\n            \"seriesBy\": \"min\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 9\n      },\n      \"id\": 7,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(controller_runtime_reconcile_total{job=\\\"$job\\\",pod=~\\\"$pod\\\",controller=~\\\"$controller\\\"}[$__rate_interval])) by (controller)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{controller}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Reconciliation Rate by controller\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"error\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"red\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"success\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"green\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"requeue\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"orange\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"requeue_after\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"blue\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 9\n      },\n      \"id\": 21,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(controller_runtime_reconcile_total{job=\\\"$job\\\",pod=~\\\"$pod\\\",controller=~\\\"$controller\\\"}[$__rate_interval])) by (result)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{result}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Reconciliation Rate by result\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"continuous-GrYlRd\",\n            \"seriesBy\": \"last\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 10,\n            \"gradientMode\": \"scheme\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 18\n      },\n      \"id\": 20,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(controller_runtime_reconcile_errors_total{job=\\\"$job\\\",pod=~\\\"$pod\\\",controller=~\\\"$controller\\\"}[$__rate_interval])) by (controller)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{controller}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Error Rate by controller\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 18\n      },\n      \"id\": 23,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile($percentile/100, sum(rate(controller_runtime_reconcile_time_seconds_bucket{job=\\\"$job\\\",pod=~\\\"$pod\\\",controller=~\\\"$controller\\\"}[$__rate_interval])) by (controller,le))\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{result}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Reconciliation Time by controller (P$percentile)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 27\n      },\n      \"id\": 32,\n      \"panels\": [],\n      \"title\": \"Workers\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"none\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 28\n      },\n      \"id\": 22,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(controller_runtime_active_workers{job=\\\"$job\\\",pod=~\\\"$pod\\\",controller=~\\\"$controller\\\"}) by (controller)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{controller}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Active Workers by controller\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"continuous-RdYlGr\"\n          },\n          \"custom\": {\n            \"align\": \"auto\",\n            \"cellOptions\": {\n              \"type\": \"auto\"\n            },\n            \"inspect\": false\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          },\n          \"unit\": \"none\"\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Value\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"custom.cellOptions\",\n                \"value\": {\n                  \"mode\": \"gradient\",\n                  \"type\": \"color-background\"\n                }\n              },\n              {\n                \"id\": \"custom.width\",\n                \"value\": 80\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"controller\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"links\",\n                \"value\": [\n                  {\n                    \"title\": \"\",\n                    \"url\": \"/d/OjCZokmVz/controller-runtime-controllers-controller-details?var-datasource=$datasource&var-job=$job&var-controller=${__data.fields.controller}\"\n                  }\n                ]\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 28\n      },\n      \"id\": 37,\n      \"options\": {\n        \"cellHeight\": \"sm\",\n        \"footer\": {\n          \"countRows\": false,\n          \"fields\": \"\",\n          \"reducer\": [\n            \"sum\"\n          ],\n          \"show\": false\n        },\n        \"showHeader\": true,\n        \"sortBy\": []\n      },\n      \"pluginVersion\": \"9.5.3\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(controller_runtime_max_concurrent_reconciles{job=\\\"$job\\\",pod=~\\\"$pod\\\",controller=~\\\"$controller\\\"}) by (controller)\",\n          \"format\": \"table\",\n          \"hide\": false,\n          \"instant\": true,\n          \"range\": false,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Total Workers by controller\",\n      \"transformations\": [\n        {\n          \"id\": \"organize\",\n          \"options\": {\n            \"excludeByName\": {\n              \"Time\": true\n            },\n            \"indexByName\": {},\n            \"renameByName\": {}\n          }\n        }\n      ],\n      \"type\": \"table\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"Rate of unfinished work per second not observed in work duration metrics. A constant value of 1 could indicate 1 stuck worker routine.\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"area\"\n            }\n          },\n          \"mappings\": [],\n          \"max\": 2,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 1\n              }\n            ]\n          },\n          \"unit\": \"none\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 37\n      },\n      \"id\": 29,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(rate(workqueue_unfinished_work_seconds{job=\\\"$job\\\",pod=~\\\"$pod\\\",name=~\\\"$controller\\\"}[$__rate_interval])) by (name)\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Unfinished Work by controller\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"continuous-GrYlRd\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"scheme\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 37\n      },\n      \"id\": 30,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"max(workqueue_longest_running_processor_seconds{job=\\\"$job\\\",pod=~\\\"$pod\\\",name=~\\\"$controller\\\"}) by (name)\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Longest Running Worker by controller\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"datasource\": {\n        \"type\": \"datasource\",\n        \"uid\": \"grafana\"\n      },\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 46\n      },\n      \"id\": 11,\n      \"panels\": [],\n      \"title\": \"Work Queue\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 47\n      },\n      \"id\": 27,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(rate(workqueue_adds_total{job=\\\"$job\\\",pod=~\\\"$pod\\\",name=~\\\"$controller\\\"}[$__rate_interval])) by (name)\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Queue Add Rate by controller\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 47\n      },\n      \"id\": 33,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(rate(workqueue_retries_total{job=\\\"$job\\\",pod=~\\\"$pod\\\",name=~\\\"$controller\\\"}[$__rate_interval])) by (name)\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Retry Rate by controller\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 56\n      },\n      \"id\": 24,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile($percentile/100, sum(rate(workqueue_queue_duration_seconds_bucket{job=\\\"$job\\\",pod=~\\\"$pod\\\",name=~\\\"$controller\\\"}[$__rate_interval])) by (name,le))\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Queue Duration by controller (P$percentile)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 56\n      },\n      \"id\": 28,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"histogram_quantile($percentile/100, sum(rate(workqueue_work_duration_seconds_bucket{job=\\\"$job\\\",pod=~\\\"$pod\\\",name=~\\\"$controller\\\"}[$__rate_interval])) by (name,le))\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Work Duration by controller (P$percentile)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              }\n            ]\n          },\n          \"unit\": \"none\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 9,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 65\n      },\n      \"id\": 25,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(workqueue_depth{job=\\\"$job\\\",pod=~\\\"$pod\\\",name=~\\\"$controller\\\"}) by (name)\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Queue Length by controller\",\n      \"type\": \"timeseries\"\n    }\n  ],\n  \"refresh\": \"10s\",\n  \"schemaVersion\": 38,\n  \"style\": \"dark\",\n  \"tags\": [\n    \"controller-runtime\"\n  ],\n  \"templating\": {\n    \"list\": [\n      {\n        \"current\": {\n          \"selected\": false,\n          \"text\": \"prometheus\",\n          \"value\": \"prometheus\"\n        },\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"multi\": false,\n        \"name\": \"datasource\",\n        \"options\": [],\n        \"query\": \"prometheus\",\n        \"queryValue\": \"\",\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"type\": \"datasource\"\n      },\n      {\n        \"allFormat\": \"glob\",\n        \"current\": {\n          \"selected\": false,\n          \"text\": \"webhosting-operator\",\n          \"value\": \"webhosting-operator\"\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(controller_runtime_reconcile_total{}, job)\",\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"multi\": false,\n        \"name\": \"job\",\n        \"options\": [],\n        \"query\": {\n          \"query\": \"label_values(controller_runtime_reconcile_total{}, job)\",\n          \"refId\": \"StandardVariableQuery\"\n        },\n        \"refresh\": 2,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"allFormat\": \"glob\",\n        \"allValue\": \".*\",\n        \"current\": {\n          \"selected\": true,\n          \"text\": [\n            \"All\"\n          ],\n          \"value\": [\n            \"$__all\"\n          ]\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(controller_runtime_reconcile_total{job=\\\"$job\\\"}, pod)\",\n        \"hide\": 0,\n        \"includeAll\": true,\n        \"multi\": true,\n        \"name\": \"pod\",\n        \"options\": [],\n        \"query\": {\n          \"query\": \"label_values(controller_runtime_reconcile_total{job=\\\"$job\\\"}, pod)\",\n          \"refId\": \"StandardVariableQuery\"\n        },\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"allFormat\": \"glob\",\n        \"allValue\": \".*\",\n        \"current\": {\n          \"selected\": true,\n          \"text\": [\n            \"All\"\n          ],\n          \"value\": [\n            \"$__all\"\n          ]\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(controller_runtime_reconcile_total{job=\\\"$job\\\"}, controller)\",\n        \"hide\": 0,\n        \"includeAll\": true,\n        \"multi\": true,\n        \"name\": \"controller\",\n        \"options\": [],\n        \"query\": {\n          \"query\": \"label_values(controller_runtime_reconcile_total{job=\\\"$job\\\"}, controller)\",\n          \"refId\": \"StandardVariableQuery\"\n        },\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"current\": {\n          \"selected\": false,\n          \"text\": \"99\",\n          \"value\": \"99\"\n        },\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"multi\": false,\n        \"name\": \"percentile\",\n        \"options\": [\n          {\n            \"selected\": false,\n            \"text\": \"90\",\n            \"value\": \"90\"\n          },\n          {\n            \"selected\": false,\n            \"text\": \"95\",\n            \"value\": \"95\"\n          },\n          {\n            \"selected\": true,\n            \"text\": \"99\",\n            \"value\": \"99\"\n          }\n        ],\n        \"query\": \"90,95,99\",\n        \"queryValue\": \"\",\n        \"skipUrlSync\": false,\n        \"type\": \"custom\"\n      }\n    ]\n  },\n  \"time\": {\n    \"from\": \"now-1h\",\n    \"to\": \"now\"\n  },\n  \"timepicker\": {},\n  \"timezone\": \"\",\n  \"title\": \"Controller Runtime / Controllers\",\n  \"uid\": \"PuCBL3zVz\",\n  \"version\": 2,\n  \"weekStart\": \"\"\n}\n"
  },
  {
    "path": "hack/config/monitoring/default/ensure-admin-password.sh",
    "content": "#!/usr/bin/env bash\n\ndir=\"$(dirname \"$0\")\"\nfile=\"$dir/grafana_admin_password.secret.txt\"\n\n[ -f \"$file\" ] && exit 0\ncat /dev/urandom | tr -dc \"a-zA-Z0-9\" | head -c 32 > \"$file\"\n"
  },
  {
    "path": "hack/config/monitoring/default/grafana_ingress.yaml",
    "content": "apiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  annotations:\n    cert-manager.io/cluster-issuer: letsencrypt-http01\n  labels:\n    app.kubernetes.io/component: grafana\n    app.kubernetes.io/name: grafana\n  name: grafana\n  namespace: monitoring\nspec:\n  rules:\n  - host: grafana.webhosting.timebertt.dev\n    http:\n      paths:\n      - backend:\n          service:\n            name: grafana\n            port:\n              name: http\n        path: /\n        pathType: Prefix\n  tls:\n  - hosts:\n    - grafana.webhosting.timebertt.dev\n    secretName: grafana-tls\n"
  },
  {
    "path": "hack/config/monitoring/default/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\ncomponents:\n- ../grafana-sidecar\n\nresources:\n- namespace.yaml\n- rbac-proxy_clusterrole.yaml\n- ../kube-prometheus\n- grafana_ingress.yaml\n\ngeneratorOptions:\n  disableNameSuffixHash: true\n\nconfigMapGenerator:\n- files:\n  - dashboards/client-go.json\n  - dashboards/controller-details.json\n  - dashboards/controller-runtime.json\n  name: grafana-dashboards-controller\n  namespace: monitoring\n  options:\n    labels:\n      grafana_dashboard: \"true\"\n\nsecretGenerator:\n- name: grafana-admin\n  namespace: monitoring\n  literals:\n  - username=admin\n  files:\n  - password=grafana_admin_password.secret.txt\n\npatches:\n- path: patch_grafana_admin.yaml\n- path: patch_prometheus.yaml\n- path: patch_grafana_networkpolicy.yaml\n  target:\n    group: networking.k8s.io\n    version: v1\n    kind: NetworkPolicy\n    name: grafana\n    namespace: monitoring\n- path: patch_kubelet_metrics.yaml\n  target:\n    group: monitoring.coreos.com\n    version: v1\n    kind: ServiceMonitor\n    name: kubelet\n    namespace: monitoring\n- path: patch_kubestatemetrics.yaml\n  target:\n    group: apps\n    version: v1\n    kind: Deployment\n    name: kube-state-metrics\n    namespace: monitoring\n- path: patch_kubestatemetrics_servicemonitor.yaml\n  target:\n    group: monitoring.coreos.com\n    version: v1\n    kind: ServiceMonitor\n    name: kube-state-metrics\n    namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/default/namespace.yaml",
    "content": "apiVersion: v1\nkind: Namespace\nmetadata:\n  name: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/default/patch_grafana_admin.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: grafana\n  namespace: monitoring\nspec:\n  template:\n    spec:\n      containers:\n      - name: grafana\n        env:\n        - name: GF_SECURITY_ADMIN_PASSWORD\n          valueFrom:\n            secretKeyRef:\n              name: grafana-admin\n              key: password\n        - name: GF_AUTH_ANONYMOUS_ENABLED\n          value: \"true\"\n        - name: GF_AUTH_ANONYMOUS_ORG_ROLE\n          value: \"Viewer\"\n        - name: GF_USERS_VIEWERS_CAN_EDIT\n          value: \"false\"\n        - name: GF_ALERTING_ENABLED\n          value: \"false\"\n        - name: GF_UNIFIED_ALERTING_ENABLED\n          value: \"false\"\n        - name: GF_USERS_DEFAULT_THEME\n          value: \"light\"\n"
  },
  {
    "path": "hack/config/monitoring/default/patch_grafana_networkpolicy.yaml",
    "content": "- op: add\n  path: /spec/ingress/-\n  value:\n    from:\n    - podSelector:\n        matchLabels:\n          app.kubernetes.io/name: ingress-nginx\n          app.kubernetes.io/component: controller\n      namespaceSelector:\n        matchLabels:\n          app.kubernetes.io/name: ingress-nginx\n    ports:\n    - port: 3000\n      protocol: TCP\n"
  },
  {
    "path": "hack/config/monitoring/default/patch_kubelet_metrics.yaml",
    "content": "# drop storage operation duration metrics (high cardinality)\n- op: add\n  path: /spec/endpoints/0/metricRelabelings/-\n  value:\n    sourceLabels: [__name__]\n    regex: storage_operation_duration_seconds_.+\n    action: drop\n# drop runtime operation duration metrics (high cardinality)\n- op: add\n  path: /spec/endpoints/0/metricRelabelings/-\n  value:\n    sourceLabels: [__name__]\n    regex: kubelet_runtime_operations_duration_seconds_.+\n    action: drop\n# drop metrics for project namespaces\n- op: add\n  path: /spec/endpoints/0/metricRelabelings/-\n  value:\n    sourceLabels: [namespace]\n    regex: project-.+\n    action: drop\n# drop cadvisor metrics for project namespaces\n- op: add\n  path: /spec/endpoints/1/metricRelabelings/-\n  value:\n    sourceLabels: [namespace]\n    regex: project-.+\n    action: drop\n# increase cadvisor scrape interval\n- op: replace\n  path: /spec/endpoints/1/interval\n  value: 10s\n"
  },
  {
    "path": "hack/config/monitoring/default/patch_kubestatemetrics.yaml",
    "content": "# drop kube-state-metrics metrics for project namespaces\n- op: add\n  path: /spec/template/spec/containers/0/args/-\n  value:\n    --namespaces=cert-manager,default,experiment,external-dns,ingress-nginx,kube-node-lease,kube-public,kube-system,kyverno,monitoring,parca,sharding-system,webhosting-system\n# label.prometheus.io/run_id is injected by experiment into observed pods (sharder and webhosting-operator).\n# Add the run_id label to kube_pod_labels. This allows joining cadvisor metrics with kube_pod_labels for selecting\n# metrics by experiment run ID.\n- op: add\n  path: /spec/template/spec/containers/0/args/-\n  value:\n    # this flag doesn't support wildcard patterns\n    --metric-labels-allowlist=pods=[label.prometheus.io/run_id]\n"
  },
  {
    "path": "hack/config/monitoring/default/patch_kubestatemetrics_servicemonitor.yaml",
    "content": "# label map for label.prometheus.io/* labels\n- op: add\n  path: /spec/endpoints/0/metricRelabelings/-\n  value:\n    action: labelmap\n    regex: \"label_label_prometheus_io_(.*)\"\n    replacement: \"${1}\"\n- op: add\n  path: /spec/endpoints/0/metricRelabelings/-\n  value:\n    action: labeldrop\n    regex: \"label_label_prometheus_io_(.*)\"\n"
  },
  {
    "path": "hack/config/monitoring/default/patch_prometheus.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: Prometheus\nmetadata:\n  name: k8s\n  namespace: monitoring\nspec:\n  replicas: 1 # don't need HA for our purposes\n  evaluationInterval: 15s\n  alerting: null\n  resources:\n    requests:\n      cpu: 3000m\n      memory: 12Gi\n    limits:\n      cpu: 4000m # replaying WAL takes some CPU\n      memory: 12Gi\n"
  },
  {
    "path": "hack/config/monitoring/default/rbac-proxy_clusterrole.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: rbac-proxy\nrules:\n- apiGroups:\n  - authentication.k8s.io\n  resources:\n  - tokenreviews\n  verbs:\n  - create\n- apiGroups:\n  - authorization.k8s.io\n  resources:\n  - subjectaccessreviews\n  verbs:\n  - create\n"
  },
  {
    "path": "hack/config/monitoring/grafana-sidecar/dashboards-sidecar.yaml",
    "content": "apiVersion: 1\nproviders:\n- folder: Default\n  folderUid: \"\"\n  name: \"1\"\n  options:\n    path: /grafana-dashboard-definitions-sidecar/0\n  orgId: 1\n  type: file\n"
  },
  {
    "path": "hack/config/monitoring/grafana-sidecar/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1alpha1\nkind: Component\n\ngeneratorOptions:\n  disableNameSuffixHash: true\n\nconfigMapGenerator:\n- name: grafana-dashboards\n  namespace: monitoring\n  behavior: merge\n  files:\n  - dashboards-sidecar.yaml\n\npatches:\n- path: patch_grafana_sidecar.yaml\n\nresources:\n- sidecar_clusterrole.yaml\n- sidecar_clusterrolebinding.yaml\n"
  },
  {
    "path": "hack/config/monitoring/grafana-sidecar/patch_grafana_sidecar.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: grafana\n  namespace: monitoring\nspec:\n  template:\n    spec:\n      automountServiceAccountToken: true\n      containers:\n      - name: grafana-sc-dashboard\n        image: quay.io/kiwigrid/k8s-sidecar:1.30.11\n        imagePullPolicy: IfNotPresent\n        env:\n        - name: METHOD\n          value: WATCH\n        - name: LABEL\n          value: grafana_dashboard\n        - name: FOLDER\n          value: /grafana-dashboard-definitions-sidecar/0\n        - name: RESOURCE\n          value: configmap\n        volumeMounts:\n        - name: sc-dashboard-volume\n          mountPath: /grafana-dashboard-definitions-sidecar/0\n      - name: grafana\n        volumeMounts:\n        - name: sc-dashboard-volume\n          mountPath: /grafana-dashboard-definitions-sidecar/0\n      volumes:\n      - name: sc-dashboard-volume\n        emptyDir: {}\n"
  },
  {
    "path": "hack/config/monitoring/grafana-sidecar/sidecar_clusterrole.yaml",
    "content": "kind: ClusterRole\napiVersion: rbac.authorization.k8s.io/v1\nmetadata:\n  labels:\n    app.kubernetes.io/name: grafana\n  name: grafana-sidecar\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - configmaps\n  verbs:\n  - get\n  - list\n  - watch\n"
  },
  {
    "path": "hack/config/monitoring/grafana-sidecar/sidecar_clusterrolebinding.yaml",
    "content": "kind: ClusterRoleBinding\napiVersion: rbac.authorization.k8s.io/v1\nmetadata:\n  labels:\n    app.kubernetes.io/name: grafana\n  name: grafana-sidecar\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: grafana-sidecar\nsubjects:\n- kind: ServiceAccount\n  name: grafana\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/README.md",
    "content": "The manifests in this directory were downloaded from\nhttps://github.com/prometheus-operator/kube-prometheus/tree/v0.16.0/manifests.\n\nBump the version in [`update.sh`](../update.sh) and run the script to update the CRDs.\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/blackboxExporter-clusterRole.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: blackbox-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.27.0\n  name: blackbox-exporter\nrules:\n- apiGroups:\n  - authentication.k8s.io\n  resources:\n  - tokenreviews\n  verbs:\n  - create\n- apiGroups:\n  - authorization.k8s.io\n  resources:\n  - subjectaccessreviews\n  verbs:\n  - create\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/blackboxExporter-clusterRoleBinding.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: blackbox-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.27.0\n  name: blackbox-exporter\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: blackbox-exporter\nsubjects:\n- kind: ServiceAccount\n  name: blackbox-exporter\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/blackboxExporter-configuration.yaml",
    "content": "apiVersion: v1\ndata:\n  config.yml: |-\n    \"modules\":\n      \"http_2xx\":\n        \"http\":\n          \"preferred_ip_protocol\": \"ip4\"\n        \"prober\": \"http\"\n      \"http_post_2xx\":\n        \"http\":\n          \"method\": \"POST\"\n          \"preferred_ip_protocol\": \"ip4\"\n        \"prober\": \"http\"\n      \"irc_banner\":\n        \"prober\": \"tcp\"\n        \"tcp\":\n          \"preferred_ip_protocol\": \"ip4\"\n          \"query_response\":\n          - \"send\": \"NICK prober\"\n          - \"send\": \"USER prober prober prober :prober\"\n          - \"expect\": \"PING :([^ ]+)\"\n            \"send\": \"PONG ${1}\"\n          - \"expect\": \"^:[^ ]+ 001\"\n      \"pop3s_banner\":\n        \"prober\": \"tcp\"\n        \"tcp\":\n          \"preferred_ip_protocol\": \"ip4\"\n          \"query_response\":\n          - \"expect\": \"^+OK\"\n          \"tls\": true\n          \"tls_config\":\n            \"insecure_skip_verify\": false\n      \"ssh_banner\":\n        \"prober\": \"tcp\"\n        \"tcp\":\n          \"preferred_ip_protocol\": \"ip4\"\n          \"query_response\":\n          - \"expect\": \"^SSH-2.0-\"\n      \"tcp_connect\":\n        \"prober\": \"tcp\"\n        \"tcp\":\n          \"preferred_ip_protocol\": \"ip4\"\nkind: ConfigMap\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: blackbox-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.27.0\n  name: blackbox-exporter-configuration\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/blackboxExporter-deployment.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: blackbox-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.27.0\n  name: blackbox-exporter\n  namespace: monitoring\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: exporter\n      app.kubernetes.io/name: blackbox-exporter\n      app.kubernetes.io/part-of: kube-prometheus\n  template:\n    metadata:\n      annotations:\n        kubectl.kubernetes.io/default-container: blackbox-exporter\n      labels:\n        app.kubernetes.io/component: exporter\n        app.kubernetes.io/name: blackbox-exporter\n        app.kubernetes.io/part-of: kube-prometheus\n        app.kubernetes.io/version: 0.27.0\n    spec:\n      automountServiceAccountToken: true\n      containers:\n      - args:\n        - --config.file=/etc/blackbox_exporter/config.yml\n        - --web.listen-address=:19115\n        image: quay.io/prometheus/blackbox-exporter:v0.27.0\n        name: blackbox-exporter\n        ports:\n        - containerPort: 19115\n          name: http\n        resources:\n          limits:\n            cpu: 20m\n            memory: 40Mi\n          requests:\n            cpu: 10m\n            memory: 20Mi\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n          readOnlyRootFilesystem: true\n          runAsGroup: 65534\n          runAsNonRoot: true\n          runAsUser: 65534\n        volumeMounts:\n        - mountPath: /etc/blackbox_exporter/\n          name: config\n          readOnly: true\n      - args:\n        - --webhook-url=http://localhost:19115/-/reload\n        - --volume-dir=/etc/blackbox_exporter/\n        image: ghcr.io/jimmidyson/configmap-reload:v0.15.0\n        name: module-configmap-reloader\n        resources:\n          limits:\n            cpu: 20m\n            memory: 40Mi\n          requests:\n            cpu: 10m\n            memory: 20Mi\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n          readOnlyRootFilesystem: true\n          runAsGroup: 65534\n          runAsNonRoot: true\n          runAsUser: 65534\n        terminationMessagePath: /dev/termination-log\n        terminationMessagePolicy: FallbackToLogsOnError\n        volumeMounts:\n        - mountPath: /etc/blackbox_exporter/\n          name: config\n          readOnly: true\n      - args:\n        - --secure-listen-address=:9115\n        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305\n        - --upstream=http://127.0.0.1:19115/\n        image: quay.io/brancz/kube-rbac-proxy:v0.19.1\n        name: kube-rbac-proxy\n        ports:\n        - containerPort: 9115\n          name: https\n        resources:\n          limits:\n            cpu: 20m\n            memory: 40Mi\n          requests:\n            cpu: 10m\n            memory: 20Mi\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n          readOnlyRootFilesystem: true\n          runAsGroup: 65532\n          runAsNonRoot: true\n          runAsUser: 65532\n          seccompProfile:\n            type: RuntimeDefault\n      nodeSelector:\n        kubernetes.io/os: linux\n      serviceAccountName: blackbox-exporter\n      volumes:\n      - configMap:\n          name: blackbox-exporter-configuration\n        name: config\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/blackboxExporter-networkPolicy.yaml",
    "content": "apiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: blackbox-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.27.0\n  name: blackbox-exporter\n  namespace: monitoring\nspec:\n  egress:\n  - {}\n  ingress:\n  - from:\n    - podSelector:\n        matchLabels:\n          app.kubernetes.io/name: prometheus\n    ports:\n    - port: 9115\n      protocol: TCP\n    - port: 19115\n      protocol: TCP\n  podSelector:\n    matchLabels:\n      app.kubernetes.io/component: exporter\n      app.kubernetes.io/name: blackbox-exporter\n      app.kubernetes.io/part-of: kube-prometheus\n  policyTypes:\n  - Egress\n  - Ingress\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/blackboxExporter-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: blackbox-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.27.0\n  name: blackbox-exporter\n  namespace: monitoring\nspec:\n  ports:\n  - name: https\n    port: 9115\n    targetPort: https\n  - name: probe\n    port: 19115\n    targetPort: http\n  selector:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: blackbox-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/blackboxExporter-serviceAccount.yaml",
    "content": "apiVersion: v1\nautomountServiceAccountToken: false\nkind: ServiceAccount\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: blackbox-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.27.0\n  name: blackbox-exporter\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/blackboxExporter-serviceMonitor.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: blackbox-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.27.0\n  name: blackbox-exporter\n  namespace: monitoring\nspec:\n  endpoints:\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    interval: 30s\n    path: /metrics\n    port: https\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: exporter\n      app.kubernetes.io/name: blackbox-exporter\n      app.kubernetes.io/part-of: kube-prometheus\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/grafana-config.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  labels:\n    app.kubernetes.io/component: grafana\n    app.kubernetes.io/name: grafana\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 12.1.0\n  name: grafana-config\n  namespace: monitoring\nstringData:\n  grafana.ini: |\n    [date_formats]\n    default_timezone = UTC\ntype: Opaque\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/grafana-dashboardDatasources.yaml",
    "content": "apiVersion: v1\nkind: Secret\nmetadata:\n  labels:\n    app.kubernetes.io/component: grafana\n    app.kubernetes.io/name: grafana\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 12.1.0\n  name: grafana-datasources\n  namespace: monitoring\nstringData:\n  datasources.yaml: |-\n    {\n        \"apiVersion\": 1,\n        \"datasources\": [\n            {\n                \"access\": \"proxy\",\n                \"editable\": false,\n                \"name\": \"prometheus\",\n                \"orgId\": 1,\n                \"type\": \"prometheus\",\n                \"url\": \"http://prometheus-k8s.monitoring.svc:9090\",\n                \"version\": 1\n            }\n        ]\n    }\ntype: Opaque\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/grafana-dashboardDefinitions.yaml",
    "content": "apiVersion: v1\nitems:\n- apiVersion: v1\n  data:\n    alertmanager-overview.json: |-\n      {\n          \"graphTooltip\": 1,\n          \"panels\": [\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Alerts\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"description\": \"current set of alerts stored in the Alertmanager\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 1\n                  },\n                  \"id\": 2,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum(alertmanager_alerts{namespace=~\\\"$namespace\\\",service=~\\\"$service\\\"}) by (namespace,service,instance)\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Alerts\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"description\": \"rate of successful and invalid alerts received by the Alertmanager\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 1\n                  },\n                  \"id\": 3,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum(rate(alertmanager_alerts_received_total{namespace=~\\\"$namespace\\\",service=~\\\"$service\\\"}[$__rate_interval])) by (namespace,service,instance)\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{instance}} Received\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum(rate(alertmanager_alerts_invalid_total{namespace=~\\\"$namespace\\\",service=~\\\"$service\\\"}[$__rate_interval])) by (namespace,service,instance)\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{instance}} Invalid\"\n                      }\n                  ],\n                  \"title\": \"Alerts receive rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 8\n                  },\n                  \"id\": 4,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Notifications\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"description\": \"rate of successful and invalid notifications sent by the Alertmanager\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 5,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"repeat\": \"integration\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum(rate(alertmanager_notifications_total{namespace=~\\\"$namespace\\\",service=~\\\"$service\\\", integration=\\\"$integration\\\"}[$__rate_interval])) by (integration,namespace,service,instance)\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{instance}} Total\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum(rate(alertmanager_notifications_failed_total{namespace=~\\\"$namespace\\\",service=~\\\"$service\\\", integration=\\\"$integration\\\"}[$__rate_interval])) by (integration,namespace,service,instance)\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{instance}} Failed\"\n                      }\n                  ],\n                  \"title\": \"$integration: Notifications Send Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"description\": \"latency of notifications sent by the Alertmanager\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 9\n                  },\n                  \"id\": 6,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"repeat\": \"integration\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99,\\n  sum(rate(alertmanager_notification_latency_seconds_bucket{namespace=~\\\"$namespace\\\",service=~\\\"$service\\\", integration=\\\"$integration\\\"}[$__rate_interval])) by (le,namespace,service,instance)\\n)\\n\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{instance}} 99th Percentile\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"histogram_quantile(0.50,\\n  sum(rate(alertmanager_notification_latency_seconds_bucket{namespace=~\\\"$namespace\\\",service=~\\\"$service\\\", integration=\\\"$integration\\\"}[$__rate_interval])) by (le,namespace,service,instance)\\n)\\n\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{instance}} Median\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum(rate(alertmanager_notification_latency_seconds_sum{namespace=~\\\"$namespace\\\",service=~\\\"$service\\\", integration=\\\"$integration\\\"}[$__rate_interval])) by (namespace,service,instance)\\n/\\nsum(rate(alertmanager_notification_latency_seconds_count{namespace=~\\\"$namespace\\\",service=~\\\"$service\\\", integration=\\\"$integration\\\"}[$__rate_interval])) by (namespace,service,instance)\\n\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{instance}} Average\"\n                      }\n                  ],\n                  \"title\": \"$integration: Notification Duration\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"alertmanager-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"Prometheus\",\n                          \"value\": \"Prometheus\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data Source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"\",\n                          \"value\": \"\"\n                      },\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"includeAll\": false,\n                      \"label\": \"namespace\",\n                      \"name\": \"namespace\",\n                      \"query\": \"label_values(alertmanager_alerts, namespace)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"\",\n                          \"value\": \"\"\n                      },\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"includeAll\": false,\n                      \"label\": \"service\",\n                      \"name\": \"service\",\n                      \"query\": \"label_values(alertmanager_alerts, service)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"$__all\",\n                          \"value\": \"$__all\"\n                      },\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 2,\n                      \"includeAll\": true,\n                      \"name\": \"integration\",\n                      \"query\": \"label_values(alertmanager_notifications_total{integration=~\\\".*\\\"}, integration)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timepicker\": {\n              \"refresh_intervals\": [\n                  \"30s\"\n              ]\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Alertmanager / Overview\",\n          \"uid\": \"alertmanager-overview\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-alertmanager-overview\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    apiserver.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"description\": \"The SLO (service level objective) and other metrics displayed on this dashboard are for informational purposes only.\",\n                  \"gridPos\": {\n                      \"h\": 2,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"options\": {\n                      \"content\": \"The SLO (service level objective) and other metrics displayed on this dashboard are for informational purposes only.\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"title\": \"Notice\",\n                  \"type\": \"text\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"description\": \"How many percent of requests (both read and write) in 30 days have been answered successfully and fast enough?\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"decimals\": 3,\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 0,\n                      \"y\": 2\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"apiserver_request:availability30d{verb=\\\"all\\\", cluster=\\\"$cluster\\\"}\"\n                      }\n                  ],\n                  \"title\": \"Availability (30d) > 99.000%\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"description\": \"How much error budget is left looking at our 0.990% availability guarantees?\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100\n                          },\n                          \"decimals\": 3,\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 16,\n                      \"x\": 8,\n                      \"y\": 2\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"100 * (apiserver_request:availability30d{verb=\\\"all\\\", cluster=\\\"$cluster\\\"} - 0.990000)\",\n                          \"legendFormat\": \"errorbudget\"\n                      }\n                  ],\n                  \"title\": \"ErrorBudget (30d) > 99.000%\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"description\": \"How many percent of read requests (LIST,GET) in 30 days have been answered successfully and fast enough?\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"decimals\": 3,\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"apiserver_request:availability30d{verb=\\\"read\\\", cluster=\\\"$cluster\\\"}\"\n                      }\n                  ],\n                  \"title\": \"Read Availability (30d)\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"description\": \"How many read requests (LIST,GET) per second do the apiservers get by code?\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"reqps\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/2../i\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": \"#56A64B\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/3../i\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": \"#F2CC0C\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/4../i\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": \"#3274D9\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/5../i\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": \"#E02F44\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 6,\n                      \"y\": 9\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (code) (code_resource:apiserver_request_total:rate5m{verb=\\\"read\\\", cluster=\\\"$cluster\\\"})\",\n                          \"legendFormat\": \"{{ code }}\"\n                      }\n                  ],\n                  \"title\": \"Read SLI - Requests\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"description\": \"How many percent of read requests (LIST,GET) per second are returned with errors (5xx)?\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"min\": 0,\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 12,\n                      \"y\": 9\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\\\"read\\\",code=~\\\"5..\\\", cluster=\\\"$cluster\\\"}) / sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\\\"read\\\", cluster=\\\"$cluster\\\"})\",\n                          \"legendFormat\": \"{{ resource }}\"\n                      }\n                  ],\n                  \"title\": \"Read SLI - Errors\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"description\": \"How many seconds is the 99th percentile for reading (LIST|GET) a given resource?\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 18,\n                      \"y\": 9\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"cluster_quantile:apiserver_request_sli_duration_seconds:histogram_quantile{verb=\\\"read\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"{{ resource }}\"\n                      }\n                  ],\n                  \"title\": \"Read SLI - Duration\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"description\": \"How many percent of write requests (POST|PUT|PATCH|DELETE) in 30 days have been answered successfully and fast enough?\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"decimals\": 3,\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 0,\n                      \"y\": 16\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"apiserver_request:availability30d{verb=\\\"write\\\", cluster=\\\"$cluster\\\"}\"\n                      }\n                  ],\n                  \"title\": \"Write Availability (30d)\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"description\": \"How many write requests (POST|PUT|PATCH|DELETE) per second do the apiservers get by code?\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"reqps\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/2../i\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": \"#56A64B\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/3../i\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": \"#F2CC0C\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/4../i\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": \"#3274D9\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/5../i\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": \"#E02F44\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 6,\n                      \"y\": 16\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (code) (code_resource:apiserver_request_total:rate5m{verb=\\\"write\\\", cluster=\\\"$cluster\\\"})\",\n                          \"legendFormat\": \"{{ code }}\"\n                      }\n                  ],\n                  \"title\": \"Write SLI - Requests\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"description\": \"How many percent of write requests (POST|PUT|PATCH|DELETE) per second are returned with errors (5xx)?\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"min\": 0,\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 12,\n                      \"y\": 16\n                  },\n                  \"id\": 10,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\\\"write\\\",code=~\\\"5..\\\", cluster=\\\"$cluster\\\"}) / sum by (resource) (code_resource:apiserver_request_total:rate5m{verb=\\\"write\\\", cluster=\\\"$cluster\\\"})\",\n                          \"legendFormat\": \"{{ resource }}\"\n                      }\n                  ],\n                  \"title\": \"Write SLI - Errors\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"description\": \"How many seconds is the 99th percentile for writing (POST|PUT|PATCH|DELETE) a given resource?\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 18,\n                      \"y\": 16\n                  },\n                  \"id\": 11,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"cluster_quantile:apiserver_request_sli_duration_seconds:histogram_quantile{verb=\\\"write\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"{{ resource }}\"\n                      }\n                  ],\n                  \"title\": \"Write SLI - Duration\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"min\": 0,\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 23\n                  },\n                  \"id\": 12,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"placement\": \"right\",\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(workqueue_adds_total{job=\\\"apiserver\\\", instance=~\\\"$instance\\\", cluster=\\\"$cluster\\\"}[$__rate_interval])) by (instance, name)\",\n                          \"legendFormat\": \"{{instance}} {{name}}\"\n                      }\n                  ],\n                  \"title\": \"Work Queue Add Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"min\": 0,\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 23\n                  },\n                  \"id\": 13,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"placement\": \"right\",\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(workqueue_depth{job=\\\"apiserver\\\", instance=~\\\"$instance\\\", cluster=\\\"$cluster\\\"}[$__rate_interval])) by (instance, name)\",\n                          \"legendFormat\": \"{{instance}} {{name}}\"\n                      }\n                  ],\n                  \"title\": \"Work Queue Depth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"min\": 0,\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 30\n                  },\n                  \"id\": 14,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{job=\\\"apiserver\\\", instance=~\\\"$instance\\\", cluster=\\\"$cluster\\\"}[$__rate_interval])) by (instance, name, le))\",\n                          \"legendFormat\": \"{{instance}} {{name}}\"\n                      }\n                  ],\n                  \"title\": \"Work Queue Latency\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 0,\n                      \"y\": 37\n                  },\n                  \"id\": 15,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"process_resident_memory_bytes{job=\\\"apiserver\\\",instance=~\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Memory\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"min\": 0,\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 8,\n                      \"y\": 37\n                  },\n                  \"id\": 16,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"rate(process_cpu_seconds_total{job=\\\"apiserver\\\",instance=~\\\"$instance\\\", cluster=\\\"$cluster\\\"}[$__rate_interval])\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"CPU usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 16,\n                      \"y\": 37\n                  },\n                  \"id\": 17,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"go_goroutines{job=\\\"apiserver\\\",instance=~\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Goroutines\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"apiserver\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"name\": \"instance\",\n                      \"query\": \"label_values(up{job=\\\"apiserver\\\", cluster=\\\"$cluster\\\"}, instance)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / API server\",\n          \"uid\": \"09ec8aa1e996d6ffcd6817bbaff4db1b\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-apiserver\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    cluster-total.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"binBps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Current Rate of Bytes Received\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"binBps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Current Rate of Bytes Transmitted\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Bytes/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"binBps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Packets/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"pps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Namespace\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down\",\n                                              \"url\": \"/d/8b7a8b326d7a6f1f04244066368c67af/kubernetes-networking-namespace-pods?${datasource:queryparam}&var-cluster=${cluster}&var-namespace=${__data.fields.Namespace}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 3,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"avg by (namespace) (\\n    rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"avg by (namespace) (\\n    rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_receive_packets_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_transmit_packets_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_receive_packets_dropped_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_transmit_packets_dropped_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Current Status\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"namespace\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true,\n                                  \"Time 7\": true,\n                                  \"Time 8\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Time 7\": 6,\n                                  \"Time 8\": 7,\n                                  \"Value #A\": 9,\n                                  \"Value #B\": 10,\n                                  \"Value #C\": 11,\n                                  \"Value #D\": 12,\n                                  \"Value #E\": 13,\n                                  \"Value #F\": 14,\n                                  \"Value #G\": 15,\n                                  \"Value #H\": 16,\n                                  \"namespace\": 8\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Rx Bytes\",\n                                  \"Value #B\": \"Tx Bytes\",\n                                  \"Value #C\": \"Rx Bytes (Avg)\",\n                                  \"Value #D\": \"Tx Bytes (Avg)\",\n                                  \"Value #E\": \"Rx Packets\",\n                                  \"Value #F\": \"Tx Packets\",\n                                  \"Value #G\": \"Rx Packets Dropped\",\n                                  \"Value #H\": \"Tx Packets Dropped\",\n                                  \"namespace\": \"Namespace\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"binBps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 18\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"avg by (namespace) (\\n    rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Average Rate of Bytes Received\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"binBps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 18\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"avg by (namespace) (\\n    rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Average Rate of Bytes Transmitted\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"binBps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 27\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Receive Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"binBps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 27\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Transmit Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 36\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_receive_packets_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 36\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_transmit_packets_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 45\n                  },\n                  \"id\": 10,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_receive_packets_dropped_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 45\n                  },\n                  \"id\": 11,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (namespace) (\\n    rate(container_network_transmit_packets_dropped_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 54\n                  },\n                  \"id\": 12,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (instance) (\\n    rate(node_netstat_Tcp_RetransSegs{cluster=\\\"$cluster\\\"}[$__rate_interval]) / rate(node_netstat_Tcp_OutSegs{cluster=\\\"$cluster\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of TCP Retransmits out of all sent segments\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 54\n                  },\n                  \"id\": 13,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (instance) (\\n    rate(node_netstat_TcpExt_TCPSynRetrans{cluster=\\\"$cluster\\\"}[$__rate_interval]) / rate(node_netstat_Tcp_RetransSegs{cluster=\\\"$cluster\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of TCP SYN Retransmits out of all retransmits\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Networking / Cluster\",\n          \"uid\": \"ff635a025bcfea7bc3dd4f508990a3e9\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-cluster-total\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    controller-manager.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 4,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(up{cluster=\\\"$cluster\\\", job=\\\"kube-controller-manager\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Up\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 20,\n                      \"x\": 4,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(workqueue_adds_total{cluster=\\\"$cluster\\\", job=\\\"kube-controller-manager\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (cluster, instance, name)\",\n                          \"legendFormat\": \"{{cluster}} {{instance}} {{name}}\"\n                      }\n                  ],\n                  \"title\": \"Work Queue Add Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(workqueue_depth{cluster=\\\"$cluster\\\", job=\\\"kube-controller-manager\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (cluster, instance, name)\",\n                          \"legendFormat\": \"{{cluster}} {{instance}} {{name}}\"\n                      }\n                  ],\n                  \"title\": \"Work Queue Depth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-controller-manager\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (cluster, instance, name, le))\",\n                          \"legendFormat\": \"{{cluster}} {{instance}} {{name}}\"\n                      }\n                  ],\n                  \"title\": \"Work Queue Latency\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{job=\\\"kube-controller-manager\\\", instance=~\\\"$instance\\\",code=~\\\"2..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"2xx\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{job=\\\"kube-controller-manager\\\", instance=~\\\"$instance\\\",code=~\\\"3..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"3xx\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{job=\\\"kube-controller-manager\\\", instance=~\\\"$instance\\\",code=~\\\"4..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"4xx\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{job=\\\"kube-controller-manager\\\", instance=~\\\"$instance\\\",code=~\\\"5..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"5xx\"\n                      }\n                  ],\n                  \"title\": \"Kube API Request Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 16,\n                      \"x\": 8,\n                      \"y\": 21\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-controller-manager\\\", instance=~\\\"$instance\\\", verb=\\\"POST\\\"}[$__rate_interval])) by (verb, le))\",\n                          \"legendFormat\": \"{{verb}}\"\n                      }\n                  ],\n                  \"title\": \"Post Request Latency 99th Quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 28\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-controller-manager\\\", instance=~\\\"$instance\\\", verb=\\\"GET\\\"}[$__rate_interval])) by (verb, le))\",\n                          \"legendFormat\": \"{{verb}}\"\n                      }\n                  ],\n                  \"title\": \"Get Request Latency 99th Quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 0,\n                      \"y\": 35\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"process_resident_memory_bytes{cluster=\\\"$cluster\\\", job=\\\"kube-controller-manager\\\",instance=~\\\"$instance\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Memory\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 8,\n                      \"y\": 35\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"rate(process_cpu_seconds_total{cluster=\\\"$cluster\\\", job=\\\"kube-controller-manager\\\",instance=~\\\"$instance\\\"}[$__rate_interval])\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"CPU usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 16,\n                      \"y\": 35\n                  },\n                  \"id\": 10,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"go_goroutines{cluster=\\\"$cluster\\\", job=\\\"kube-controller-manager\\\",instance=~\\\"$instance\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Goroutines\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kube-controller-manager\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": \"instance\",\n                      \"name\": \"instance\",\n                      \"query\": \"label_values(up{cluster=\\\"$cluster\\\", job=\\\"kube-controller-manager\\\"}, instance)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Controller Manager\",\n          \"uid\": \"72e0e05bef5099e5f049b05fdc429ed4\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-controller-manager\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    grafana-overview.json: |-\n      {\n          \"annotations\": {\n              \"list\": [\n                  {\n                      \"builtIn\": 1,\n                      \"datasource\": \"-- Grafana --\",\n                      \"enable\": true,\n                      \"hide\": true,\n                      \"iconColor\": \"rgba(0, 211, 255, 1)\",\n                      \"name\": \"Annotations & Alerts\",\n                      \"target\": {\n                          \"limit\": 100,\n                          \"matchAny\": false,\n                          \"tags\": [\n\n                          ],\n                          \"type\": \"dashboard\"\n                      },\n                      \"type\": \"dashboard\"\n                  }\n              ]\n          },\n          \"editable\": true,\n          \"gnetId\": null,\n          \"graphTooltip\": 0,\n          \"id\": 3085,\n          \"iteration\": 1631554945276,\n          \"links\": [\n\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": \"$datasource\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"mappings\": [\n\n                          ],\n                          \"noValue\": \"0\",\n                          \"thresholds\": {\n                              \"mode\": \"absolute\",\n                              \"steps\": [\n                                  {\n                                      \"color\": \"green\",\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"color\": \"red\",\n                                      \"value\": 80\n                                  }\n                              ]\n                          }\n                      },\n                      \"overrides\": [\n\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 5,\n                      \"w\": 6,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 6,\n                  \"options\": {\n                      \"colorMode\": \"value\",\n                      \"graphMode\": \"area\",\n                      \"justifyMode\": \"auto\",\n                      \"orientation\": \"auto\",\n                      \"reduceOptions\": {\n                          \"calcs\": [\n                              \"mean\"\n                          ],\n                          \"fields\": \"\",\n                          \"values\": false\n                      },\n                      \"text\": {\n\n                      },\n                      \"textMode\": \"auto\"\n                  },\n                  \"pluginVersion\": \"8.1.3\",\n                  \"targets\": [\n                      {\n                          \"expr\": \"grafana_alerting_result_total{job=~\\\"$job\\\", instance=~\\\"$instance\\\", state=\\\"alerting\\\"}\",\n                          \"instant\": true,\n                          \"interval\": \"\",\n                          \"legendFormat\": \"\",\n                          \"refId\": \"A\"\n                      }\n                  ],\n                  \"timeFrom\": null,\n                  \"timeShift\": null,\n                  \"title\": \"Firing Alerts\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": \"$datasource\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"mappings\": [\n\n                          ],\n                          \"thresholds\": {\n                              \"mode\": \"absolute\",\n                              \"steps\": [\n                                  {\n                                      \"color\": \"green\",\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"color\": \"red\",\n                                      \"value\": 80\n                                  }\n                              ]\n                          }\n                      },\n                      \"overrides\": [\n\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 5,\n                      \"w\": 6,\n                      \"x\": 6,\n                      \"y\": 0\n                  },\n                  \"id\": 8,\n                  \"options\": {\n                      \"colorMode\": \"value\",\n                      \"graphMode\": \"area\",\n                      \"justifyMode\": \"auto\",\n                      \"orientation\": \"auto\",\n                      \"reduceOptions\": {\n                          \"calcs\": [\n                              \"mean\"\n                          ],\n                          \"fields\": \"\",\n                          \"values\": false\n                      },\n                      \"text\": {\n\n                      },\n                      \"textMode\": \"auto\"\n                  },\n                  \"pluginVersion\": \"8.1.3\",\n                  \"targets\": [\n                      {\n                          \"expr\": \"sum(grafana_stat_totals_dashboard{job=~\\\"$job\\\", instance=~\\\"$instance\\\"})\",\n                          \"interval\": \"\",\n                          \"legendFormat\": \"\",\n                          \"refId\": \"A\"\n                      }\n                  ],\n                  \"timeFrom\": null,\n                  \"timeShift\": null,\n                  \"title\": \"Dashboards\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": \"$datasource\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"align\": null,\n                              \"displayMode\": \"auto\"\n                          },\n                          \"mappings\": [\n\n                          ],\n                          \"thresholds\": {\n                              \"mode\": \"absolute\",\n                              \"steps\": [\n                                  {\n                                      \"color\": \"green\",\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"color\": \"red\",\n                                      \"value\": 80\n                                  }\n                              ]\n                          }\n                      },\n                      \"overrides\": [\n\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 5,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 0\n                  },\n                  \"id\": 10,\n                  \"options\": {\n                      \"showHeader\": true\n                  },\n                  \"pluginVersion\": \"8.1.3\",\n                  \"targets\": [\n                      {\n                          \"expr\": \"grafana_build_info{job=~\\\"$job\\\", instance=~\\\"$instance\\\"}\",\n                          \"instant\": true,\n                          \"interval\": \"\",\n                          \"legendFormat\": \"\",\n                          \"refId\": \"A\"\n                      }\n                  ],\n                  \"timeFrom\": null,\n                  \"timeShift\": null,\n                  \"title\": \"Build Info\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"labelsToFields\",\n                          \"options\": {\n\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Value\": true,\n                                  \"branch\": true,\n                                  \"container\": true,\n                                  \"goversion\": true,\n                                  \"namespace\": true,\n                                  \"pod\": true,\n                                  \"revision\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time\": 7,\n                                  \"Value\": 11,\n                                  \"branch\": 4,\n                                  \"container\": 8,\n                                  \"edition\": 2,\n                                  \"goversion\": 6,\n                                  \"instance\": 1,\n                                  \"job\": 0,\n                                  \"namespace\": 9,\n                                  \"pod\": 10,\n                                  \"revision\": 5,\n                                  \"version\": 3\n                              },\n                              \"renameByName\": {\n\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"aliasColors\": {\n\n                  },\n                  \"bars\": false,\n                  \"dashLength\": 10,\n                  \"dashes\": false,\n                  \"datasource\": \"$datasource\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"links\": [\n\n                          ]\n                      },\n                      \"overrides\": [\n\n                      ]\n                  },\n                  \"fill\": 1,\n                  \"fillGradient\": 0,\n                  \"gridPos\": {\n                      \"h\": 8,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 5\n                  },\n                  \"hiddenSeries\": false,\n                  \"id\": 2,\n                  \"legend\": {\n                      \"avg\": false,\n                      \"current\": false,\n                      \"max\": false,\n                      \"min\": false,\n                      \"show\": true,\n                      \"total\": false,\n                      \"values\": false\n                  },\n                  \"lines\": true,\n                  \"linewidth\": 1,\n                  \"nullPointMode\": \"null\",\n                  \"options\": {\n                      \"alertThreshold\": true\n                  },\n                  \"percentage\": false,\n                  \"pluginVersion\": \"8.1.3\",\n                  \"pointradius\": 2,\n                  \"points\": false,\n                  \"renderer\": \"flot\",\n                  \"seriesOverrides\": [\n\n                  ],\n                  \"spaceLength\": 10,\n                  \"stack\": true,\n                  \"steppedLine\": false,\n                  \"targets\": [\n                      {\n                          \"expr\": \"sum by (status_code) (irate(grafana_http_request_duration_seconds_count{job=~\\\"$job\\\", instance=~\\\"$instance\\\"}[1m])) \",\n                          \"interval\": \"\",\n                          \"legendFormat\": \"{{status_code}}\",\n                          \"refId\": \"A\"\n                      }\n                  ],\n                  \"thresholds\": [\n\n                  ],\n                  \"timeFrom\": null,\n                  \"timeRegions\": [\n\n                  ],\n                  \"timeShift\": null,\n                  \"title\": \"RPS\",\n                  \"tooltip\": {\n                      \"shared\": true,\n                      \"sort\": 0,\n                      \"value_type\": \"individual\"\n                  },\n                  \"type\": \"graph\",\n                  \"xaxis\": {\n                      \"buckets\": null,\n                      \"mode\": \"time\",\n                      \"name\": null,\n                      \"show\": true,\n                      \"values\": [\n\n                      ]\n                  },\n                  \"yaxes\": [\n                      {\n                          \"$$hashKey\": \"object:157\",\n                          \"format\": \"reqps\",\n                          \"label\": null,\n                          \"logBase\": 1,\n                          \"max\": null,\n                          \"min\": null,\n                          \"show\": true\n                      },\n                      {\n                          \"$$hashKey\": \"object:158\",\n                          \"format\": \"short\",\n                          \"label\": null,\n                          \"logBase\": 1,\n                          \"max\": null,\n                          \"min\": null,\n                          \"show\": false\n                      }\n                  ],\n                  \"yaxis\": {\n                      \"align\": false,\n                      \"alignLevel\": null\n                  }\n              },\n              {\n                  \"aliasColors\": {\n\n                  },\n                  \"bars\": false,\n                  \"dashLength\": 10,\n                  \"dashes\": false,\n                  \"datasource\": \"$datasource\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"links\": [\n\n                          ]\n                      },\n                      \"overrides\": [\n\n                      ]\n                  },\n                  \"fill\": 1,\n                  \"fillGradient\": 0,\n                  \"gridPos\": {\n                      \"h\": 8,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 5\n                  },\n                  \"hiddenSeries\": false,\n                  \"id\": 4,\n                  \"legend\": {\n                      \"avg\": false,\n                      \"current\": false,\n                      \"max\": false,\n                      \"min\": false,\n                      \"show\": true,\n                      \"total\": false,\n                      \"values\": false\n                  },\n                  \"lines\": true,\n                  \"linewidth\": 1,\n                  \"nullPointMode\": \"null\",\n                  \"options\": {\n                      \"alertThreshold\": true\n                  },\n                  \"percentage\": false,\n                  \"pluginVersion\": \"8.1.3\",\n                  \"pointradius\": 2,\n                  \"points\": false,\n                  \"renderer\": \"flot\",\n                  \"seriesOverrides\": [\n\n                  ],\n                  \"spaceLength\": 10,\n                  \"stack\": false,\n                  \"steppedLine\": false,\n                  \"targets\": [\n                      {\n                          \"exemplar\": true,\n                          \"expr\": \"histogram_quantile(0.99, sum(irate(grafana_http_request_duration_seconds_bucket{instance=~\\\"$instance\\\", job=~\\\"$job\\\"}[$__rate_interval])) by (le)) * 1\",\n                          \"interval\": \"\",\n                          \"legendFormat\": \"99th Percentile\",\n                          \"refId\": \"A\"\n                      },\n                      {\n                          \"exemplar\": true,\n                          \"expr\": \"histogram_quantile(0.50, sum(irate(grafana_http_request_duration_seconds_bucket{instance=~\\\"$instance\\\", job=~\\\"$job\\\"}[$__rate_interval])) by (le)) * 1\",\n                          \"interval\": \"\",\n                          \"legendFormat\": \"50th Percentile\",\n                          \"refId\": \"B\"\n                      },\n                      {\n                          \"exemplar\": true,\n                          \"expr\": \"sum(irate(grafana_http_request_duration_seconds_sum{instance=~\\\"$instance\\\", job=~\\\"$job\\\"}[$__rate_interval])) * 1 / sum(irate(grafana_http_request_duration_seconds_count{instance=~\\\"$instance\\\", job=~\\\"$job\\\"}[$__rate_interval]))\",\n                          \"interval\": \"\",\n                          \"legendFormat\": \"Average\",\n                          \"refId\": \"C\"\n                      }\n                  ],\n                  \"thresholds\": [\n\n                  ],\n                  \"timeFrom\": null,\n                  \"timeRegions\": [\n\n                  ],\n                  \"timeShift\": null,\n                  \"title\": \"Request Latency\",\n                  \"tooltip\": {\n                      \"shared\": true,\n                      \"sort\": 0,\n                      \"value_type\": \"individual\"\n                  },\n                  \"type\": \"graph\",\n                  \"xaxis\": {\n                      \"buckets\": null,\n                      \"mode\": \"time\",\n                      \"name\": null,\n                      \"show\": true,\n                      \"values\": [\n\n                      ]\n                  },\n                  \"yaxes\": [\n                      {\n                          \"$$hashKey\": \"object:210\",\n                          \"format\": \"ms\",\n                          \"label\": null,\n                          \"logBase\": 1,\n                          \"max\": null,\n                          \"min\": null,\n                          \"show\": true\n                      },\n                      {\n                          \"$$hashKey\": \"object:211\",\n                          \"format\": \"short\",\n                          \"label\": null,\n                          \"logBase\": 1,\n                          \"max\": null,\n                          \"min\": null,\n                          \"show\": true\n                      }\n                  ],\n                  \"yaxis\": {\n                      \"align\": false,\n                      \"alignLevel\": null\n                  }\n              }\n          ],\n          \"schemaVersion\": 30,\n          \"tags\": [\n\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"dev-cortex\",\n                          \"value\": \"dev-cortex\"\n                      },\n                      \"description\": null,\n                      \"error\": null,\n                      \"hide\": 0,\n                      \"includeAll\": false,\n                      \"label\": null,\n                      \"multi\": false,\n                      \"name\": \"datasource\",\n                      \"options\": [\n\n                      ],\n                      \"query\": \"prometheus\",\n                      \"queryValue\": \"\",\n                      \"refresh\": 1,\n                      \"regex\": \"\",\n                      \"skipUrlSync\": false,\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"allValue\": \".*\",\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": [\n                              \"default/grafana\"\n                          ],\n                          \"value\": [\n                              \"default/grafana\"\n                          ]\n                      },\n                      \"datasource\": \"$datasource\",\n                      \"definition\": \"label_values(grafana_build_info, job)\",\n                      \"description\": null,\n                      \"error\": null,\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": null,\n                      \"multi\": true,\n                      \"name\": \"job\",\n                      \"options\": [\n\n                      ],\n                      \"query\": {\n                          \"query\": \"label_values(grafana_build_info, job)\",\n                          \"refId\": \"Billing Admin-job-Variable-Query\"\n                      },\n                      \"refresh\": 1,\n                      \"regex\": \"\",\n                      \"skipUrlSync\": false,\n                      \"sort\": 0,\n                      \"tagValuesQuery\": \"\",\n                      \"tagsQuery\": \"\",\n                      \"type\": \"query\",\n                      \"useTags\": false\n                  },\n                  {\n                      \"allValue\": \".*\",\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"All\",\n                          \"value\": \"$__all\"\n                      },\n                      \"datasource\": \"$datasource\",\n                      \"definition\": \"label_values(grafana_build_info, instance)\",\n                      \"description\": null,\n                      \"error\": null,\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": null,\n                      \"multi\": true,\n                      \"name\": \"instance\",\n                      \"options\": [\n\n                      ],\n                      \"query\": {\n                          \"query\": \"label_values(grafana_build_info, instance)\",\n                          \"refId\": \"Billing Admin-instance-Variable-Query\"\n                      },\n                      \"refresh\": 1,\n                      \"regex\": \"\",\n                      \"skipUrlSync\": false,\n                      \"sort\": 0,\n                      \"tagValuesQuery\": \"\",\n                      \"tagsQuery\": \"\",\n                      \"type\": \"query\",\n                      \"useTags\": false\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-6h\",\n              \"to\": \"now\"\n          },\n          \"timepicker\": {\n              \"refresh_intervals\": [\n                  \"10s\",\n                  \"30s\",\n                  \"1m\",\n                  \"5m\",\n                  \"15m\",\n                  \"30m\",\n                  \"1h\",\n                  \"2h\",\n                  \"1d\"\n              ]\n          },\n          \"timezone\": \"\",\n          \"title\": \"Grafana Overview\",\n          \"uid\": \"6be0s85Mk\",\n          \"version\": 2\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-grafana-overview\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    k8s-resources-cluster.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"cluster:node_cpu:ratio_rate5m{cluster=\\\"$cluster\\\"}\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Utilisation\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 4,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_cpu:kube_pod_container_resource_requests:sum{cluster=\\\"$cluster\\\"}) / sum(kube_node_status_allocatable{job=\\\"kube-state-metrics\\\",resource=\\\"cpu\\\",cluster=\\\"$cluster\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Requests Commitment\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 8,\n                      \"y\": 0\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_cpu:kube_pod_container_resource_limits:sum{cluster=\\\"$cluster\\\"}) / sum(kube_node_status_allocatable{job=\\\"kube-state-metrics\\\",resource=\\\"cpu\\\",cluster=\\\"$cluster\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Limits Commitment\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 12,\n                      \"y\": 0\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"1 - sum(:node_memory_MemAvailable_bytes:sum{cluster=\\\"$cluster\\\"}) / sum(node_memory_MemTotal_bytes{job=\\\"node-exporter\\\",cluster=\\\"$cluster\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Utilisation\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 16,\n                      \"y\": 0\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_memory:kube_pod_container_resource_requests:sum{cluster=\\\"$cluster\\\"}) / sum(kube_node_status_allocatable{job=\\\"kube-state-metrics\\\",resource=\\\"memory\\\",cluster=\\\"$cluster\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Requests Commitment\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 20,\n                      \"y\": 0\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_memory:kube_pod_container_resource_limits:sum{cluster=\\\"$cluster\\\"}) / sum(kube_node_status_allocatable{job=\\\"kube-state-metrics\\\",resource=\\\"memory\\\",cluster=\\\"$cluster\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Limits Commitment\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          }\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 6\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Namespace\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 12\n                  },\n                  \"id\": 8,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_owner{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"count(avg(namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\"}) by (workload, namespace)) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_cpu:kube_pod_container_resource_requests:sum{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\"}) by (namespace) / sum(namespace_cpu:kube_pod_container_resource_requests:sum{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_cpu:kube_pod_container_resource_limits:sum{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\"}) by (namespace) / sum(namespace_cpu:kube_pod_container_resource_limits:sum{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"namespace\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true,\n                                  \"Time 7\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Time 7\": 6,\n                                  \"Value #A\": 8,\n                                  \"Value #B\": 9,\n                                  \"Value #C\": 10,\n                                  \"Value #D\": 11,\n                                  \"Value #E\": 12,\n                                  \"Value #F\": 13,\n                                  \"Value #G\": 14,\n                                  \"namespace\": 7\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Pods\",\n                                  \"Value #B\": \"Workloads\",\n                                  \"Value #C\": \"CPU Usage\",\n                                  \"Value #D\": \"CPU Requests\",\n                                  \"Value #E\": \"CPU Requests %\",\n                                  \"Value #F\": \"CPU Limits\",\n                                  \"Value #G\": \"CPU Limits %\",\n                                  \"namespace\": \"Namespace\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 18\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_rss{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", container!=\\\"\\\"}) by (namespace)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Memory\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Memory Usage\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"bytes\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Memory Requests\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"bytes\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Memory Limits\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"bytes\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Namespace\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 24\n                  },\n                  \"id\": 10,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_owner{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"count(avg(namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\"}) by (workload, namespace)) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_rss{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", container!=\\\"\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_memory:kube_pod_container_resource_requests:sum{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_rss{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", container!=\\\"\\\"}) by (namespace) / sum(namespace_memory:kube_pod_container_resource_requests:sum{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_memory:kube_pod_container_resource_limits:sum{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_rss{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", container!=\\\"\\\"}) by (namespace) / sum(namespace_memory:kube_pod_container_resource_limits:sum{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Requests by Namespace\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"namespace\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true,\n                                  \"Time 7\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Time 7\": 6,\n                                  \"Value #A\": 8,\n                                  \"Value #B\": 9,\n                                  \"Value #C\": 10,\n                                  \"Value #D\": 11,\n                                  \"Value #E\": 12,\n                                  \"Value #F\": 13,\n                                  \"Value #G\": 14,\n                                  \"namespace\": 7\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Pods\",\n                                  \"Value #B\": \"Workloads\",\n                                  \"Value #C\": \"Memory Usage\",\n                                  \"Value #D\": \"Memory Requests\",\n                                  \"Value #E\": \"Memory Requests %\",\n                                  \"Value #F\": \"Memory Limits\",\n                                  \"Value #G\": \"Memory Limits %\",\n                                  \"namespace\": \"Namespace\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Bandwidth/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"Bps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Packets/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"pps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Namespace\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 30\n                  },\n                  \"id\": 11,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Current Network Usage\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"namespace\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Value #A\": 7,\n                                  \"Value #B\": 8,\n                                  \"Value #C\": 9,\n                                  \"Value #D\": 10,\n                                  \"Value #E\": 11,\n                                  \"Value #F\": 12,\n                                  \"namespace\": 6\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Current Receive Bandwidth\",\n                                  \"Value #B\": \"Current Transmit Bandwidth\",\n                                  \"Value #C\": \"Rate of Received Packets\",\n                                  \"Value #D\": \"Rate of Transmitted Packets\",\n                                  \"Value #E\": \"Rate of Received Packets Dropped\",\n                                  \"Value #F\": \"Rate of Transmitted Packets Dropped\",\n                                  \"namespace\": \"Namespace\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 36\n                  },\n                  \"id\": 12,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Receive Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 42\n                  },\n                  \"id\": 13,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Transmit Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 48\n                  },\n                  \"id\": 14,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"avg(irate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Average Container Bandwidth by Namespace: Received\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 54\n                  },\n                  \"id\": 15,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"avg(irate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Average Container Bandwidth by Namespace: Transmitted\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 60\n                  },\n                  \"id\": 16,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(irate(container_network_receive_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 66\n                  },\n                  \"id\": 17,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(irate(container_network_transmit_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 72\n                  },\n                  \"id\": 18,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(irate(container_network_receive_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 78\n                  },\n                  \"id\": 19,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(irate(container_network_transmit_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=~\\\".+\\\"}[$__rate_interval])) by (namespace)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"iops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 84\n                  },\n                  \"id\": 20,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"ceil(sum by(namespace) (rate(container_fs_reads_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", container!=\\\"\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", cluster=\\\"$cluster\\\", namespace!=\\\"\\\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace!=\\\"\\\"}[$__rate_interval])))\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"IOPS(Reads+Writes)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 90\n                  },\n                  \"id\": 21,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(namespace) (rate(container_fs_reads_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", container!=\\\"\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", cluster=\\\"$cluster\\\", namespace!=\\\"\\\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace!=\\\"\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"ThroughPut(Read+Write)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/IOPS/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"iops\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Throughput/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"Bps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Namespace\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/85a562078cdf77779eaa1add43ccec1e/k8s-resources-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 96\n                  },\n                  \"id\": 22,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(namespace) (rate(container_fs_reads_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace!=\\\"\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(namespace) (rate(container_fs_writes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace!=\\\"\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(namespace) (rate(container_fs_reads_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace!=\\\"\\\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace!=\\\"\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(namespace) (rate(container_fs_reads_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace!=\\\"\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(namespace) (rate(container_fs_writes_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace!=\\\"\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(namespace) (rate(container_fs_reads_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace!=\\\"\\\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace!=\\\"\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Current Storage IO\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"namespace\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Value #A\": 7,\n                                  \"Value #B\": 8,\n                                  \"Value #C\": 9,\n                                  \"Value #D\": 10,\n                                  \"Value #E\": 11,\n                                  \"Value #F\": 12,\n                                  \"namespace\": 6\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"IOPS(Reads)\",\n                                  \"Value #B\": \"IOPS(Writes)\",\n                                  \"Value #C\": \"IOPS(Reads + Writes)\",\n                                  \"Value #D\": \"Throughput(Read)\",\n                                  \"Value #E\": \"Throughput(Write)\",\n                                  \"Value #F\": \"Throughput(Read + Write)\",\n                                  \"namespace\": \"Namespace\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Compute Resources / Cluster\",\n          \"uid\": \"efa86fd1d0c121a26444b636a3f509a8\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-k8s-resources-cluster\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    k8s-resources-multicluster.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:node_cpu:ratio_rate5m) / count(cluster:node_cpu:ratio_rate5m)\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Utilisation\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 4,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", resource=\\\"cpu\\\"}) / sum(kube_node_status_allocatable{job=\\\"kube-state-metrics\\\", resource=\\\"cpu\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Requests Commitment\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 8,\n                      \"y\": 0\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", resource=\\\"cpu\\\"}) / sum(kube_node_status_allocatable{job=\\\"kube-state-metrics\\\", resource=\\\"cpu\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Limits Commitment\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 12,\n                      \"y\": 0\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"1 - sum(:node_memory_MemAvailable_bytes:sum) / sum(node_memory_MemTotal_bytes{job=\\\"node-exporter\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Utilisation\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 16,\n                      \"y\": 0\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", resource=\\\"memory\\\"}) / sum(kube_node_status_allocatable{job=\\\"kube-state-metrics\\\", resource=\\\"memory\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Requests Commitment\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 20,\n                      \"y\": 0\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", resource=\\\"memory\\\"}) / sum(kube_node_status_allocatable{job=\\\"kube-state-metrics\\\", resource=\\\"memory\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Limits Commitment\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          }\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 1\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m) by (cluster)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Cluster\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down\",\n                                              \"url\": \"/d/efa86fd1d0c121a26444b636a3f509a8/kubernetes-compute-resources-cluster?${datasource:queryparam}&var-cluster=${__data.fields.Cluster}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 2\n                  },\n                  \"id\": 8,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m) by (cluster)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", resource=\\\"cpu\\\"}) by (cluster)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m) by (cluster) / sum(kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", resource=\\\"cpu\\\"}) by (cluster)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", resource=\\\"cpu\\\"}) by (cluster)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m) by (cluster) / sum(kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", resource=\\\"cpu\\\"}) by (cluster)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"cluster\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Value #A\": 6,\n                                  \"Value #B\": 7,\n                                  \"Value #C\": 8,\n                                  \"Value #D\": 9,\n                                  \"Value #E\": 10,\n                                  \"cluster\": 5\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"CPU Usage\",\n                                  \"Value #B\": \"CPU Requests\",\n                                  \"Value #C\": \"CPU Requests %\",\n                                  \"Value #D\": \"CPU Limits\",\n                                  \"Value #E\": \"CPU Limits %\",\n                                  \"cluster\": \"Cluster\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 3\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_rss{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", container!=\\\"\\\"}) by (cluster)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage (w/o cache)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Cluster\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down\",\n                                              \"url\": \"/d/efa86fd1d0c121a26444b636a3f509a8/kubernetes-compute-resources-cluster?${datasource:queryparam}&var-cluster=${__data.fields.Cluster}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 4\n                  },\n                  \"id\": 10,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_rss{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", container!=\\\"\\\"}) by (cluster)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", resource=\\\"memory\\\"}) by (cluster)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_rss{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", container!=\\\"\\\"}) by (cluster) / sum(kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", resource=\\\"memory\\\"}) by (cluster)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", resource=\\\"memory\\\"}) by (cluster)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_rss{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", container!=\\\"\\\"}) by (cluster) / sum(kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", resource=\\\"memory\\\"}) by (cluster)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Requests by Cluster\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"cluster\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Value #A\": 6,\n                                  \"Value #B\": 7,\n                                  \"Value #C\": 8,\n                                  \"Value #D\": 9,\n                                  \"Value #E\": 10,\n                                  \"cluster\": 5\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Memory Usage\",\n                                  \"Value #B\": \"Memory Requests\",\n                                  \"Value #C\": \"Memory Requests %\",\n                                  \"Value #D\": \"Memory Limits\",\n                                  \"Value #E\": \"Memory Limits %\",\n                                  \"cluster\": \"Cluster\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Compute Resources /  Multi-Cluster\",\n          \"uid\": \"b59e6c9f2fcbe2e16d77fc492374cc4f\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-k8s-resources-multicluster\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    k8s-resources-namespace.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 6,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) / sum(kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"cpu\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Utilisation (from requests)\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 6,\n                      \"x\": 6,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) / sum(kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"cpu\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Utilisation (from limits)\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 6,\n                      \"x\": 12,\n                      \"y\": 0\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\",container!=\\\"\\\", image!=\\\"\\\"}) / sum(kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"memory\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Utilisation (from requests)\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 6,\n                      \"x\": 18,\n                      \"y\": 0\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\",container!=\\\"\\\", image!=\\\"\\\"}) / sum(kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"memory\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Utilisation (from limits)\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          }\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"B\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"fill\": \"dash\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineWidth\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"red\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"C\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"fill\": \"dash\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineWidth\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"orange\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"scalar(max(kube_resourcequota{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", type=\\\"hard\\\",resource=\\\"requests.cpu\\\"}))\",\n                          \"legendFormat\": \"quota - requests\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"scalar(max(kube_resourcequota{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", type=\\\"hard\\\",resource=\\\"limits.cpu\\\"}))\",\n                          \"legendFormat\": \"quota - limits\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Pod\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 6,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"pod\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Value #A\": 6,\n                                  \"Value #B\": 7,\n                                  \"Value #C\": 8,\n                                  \"Value #D\": 9,\n                                  \"Value #E\": 10,\n                                  \"pod\": 5\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"CPU Usage\",\n                                  \"Value #B\": \"CPU Requests\",\n                                  \"Value #C\": \"CPU Requests %\",\n                                  \"Value #D\": \"CPU Limits\",\n                                  \"Value #E\": \"CPU Limits %\",\n                                  \"pod\": \"Pod\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"B\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"fill\": \"dash\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineWidth\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"red\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"C\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"fill\": \"dash\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineWidth\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"orange\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", container!=\\\"\\\", image!=\\\"\\\"}) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"scalar(max(kube_resourcequota{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", type=\\\"hard\\\",resource=\\\"requests.memory\\\"}))\",\n                          \"legendFormat\": \"quota - requests\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"scalar(max(kube_resourcequota{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", type=\\\"hard\\\",resource=\\\"limits.memory\\\"}))\",\n                          \"legendFormat\": \"quota - limits\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage (w/o cache)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Pod\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 28\n                  },\n                  \"id\": 8,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\",container!=\\\"\\\", image!=\\\"\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\",container!=\\\"\\\", image!=\\\"\\\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\",container!=\\\"\\\", image!=\\\"\\\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_rss{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\",container!=\\\"\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_cache{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\",container!=\\\"\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_swap{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\",container!=\\\"\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"pod\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true,\n                                  \"Time 7\": true,\n                                  \"Time 8\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Time 7\": 6,\n                                  \"Time 8\": 7,\n                                  \"Value #A\": 9,\n                                  \"Value #B\": 10,\n                                  \"Value #C\": 11,\n                                  \"Value #D\": 12,\n                                  \"Value #E\": 13,\n                                  \"Value #F\": 14,\n                                  \"Value #G\": 15,\n                                  \"Value #H\": 16,\n                                  \"pod\": 8\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Memory Usage\",\n                                  \"Value #B\": \"Memory Requests\",\n                                  \"Value #C\": \"Memory Requests %\",\n                                  \"Value #D\": \"Memory Limits\",\n                                  \"Value #E\": \"Memory Limits %\",\n                                  \"Value #F\": \"Memory Usage (RSS)\",\n                                  \"Value #G\": \"Memory Usage (Cache)\",\n                                  \"Value #H\": \"Memory Usage (Swap)\",\n                                  \"pod\": \"Pod\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Bandwidth/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"Bps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Packets/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"pps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Pod\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 35\n                  },\n                  \"id\": 9,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Current Network Usage\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"pod\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Value #A\": 7,\n                                  \"Value #B\": 8,\n                                  \"Value #C\": 9,\n                                  \"Value #D\": 10,\n                                  \"Value #E\": 11,\n                                  \"Value #F\": 12,\n                                  \"pod\": 6\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Current Receive Bandwidth\",\n                                  \"Value #B\": \"Current Transmit Bandwidth\",\n                                  \"Value #C\": \"Rate of Received Packets\",\n                                  \"Value #D\": \"Rate of Transmitted Packets\",\n                                  \"Value #E\": \"Rate of Received Packets Dropped\",\n                                  \"Value #F\": \"Rate of Transmitted Packets Dropped\",\n                                  \"pod\": \"Pod\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 42\n                  },\n                  \"id\": 10,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Receive Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 42\n                  },\n                  \"id\": 11,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Transmit Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 49\n                  },\n                  \"id\": 12,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(irate(container_network_receive_packets_total{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 49\n                  },\n                  \"id\": 13,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(irate(container_network_transmit_packets_total{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 56\n                  },\n                  \"id\": 14,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(irate(container_network_receive_packets_dropped_total{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 56\n                  },\n                  \"id\": 15,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(irate(container_network_transmit_packets_dropped_total{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"iops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 63\n                  },\n                  \"id\": 16,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"ceil(sum by(pod) (rate(container_fs_reads_total{container!=\\\"\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval]) + rate(container_fs_writes_total{container!=\\\"\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])))\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"IOPS(Reads+Writes)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 63\n                  },\n                  \"id\": 17,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(pod) (rate(container_fs_reads_bytes_total{container!=\\\"\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{container!=\\\"\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"ThroughPut(Read+Write)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/IOPS/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"iops\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Throughput/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"Bps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Pod\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 70\n                  },\n                  \"id\": 18,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(pod) (rate(container_fs_reads_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(pod) (rate(container_fs_writes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(pod) (rate(container_fs_reads_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(pod) (rate(container_fs_reads_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(pod) (rate(container_fs_writes_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(pod) (rate(container_fs_reads_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Current Storage IO\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"pod\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Value #A\": 7,\n                                  \"Value #B\": 8,\n                                  \"Value #C\": 9,\n                                  \"Value #D\": 10,\n                                  \"Value #E\": 11,\n                                  \"Value #F\": 12,\n                                  \"pod\": 6\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"IOPS(Reads)\",\n                                  \"Value #B\": \"IOPS(Writes)\",\n                                  \"Value #C\": \"IOPS(Reads + Writes)\",\n                                  \"Value #D\": \"Throughput(Read)\",\n                                  \"Value #E\": \"Throughput(Write)\",\n                                  \"Value #F\": \"Throughput(Read + Write)\",\n                                  \"pod\": \"Pod\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kube-state-metrics\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"namespace\",\n                      \"name\": \"namespace\",\n                      \"query\": \"label_values(kube_namespace_status_phase{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\"}, namespace)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Compute Resources / Namespace (Pods)\",\n          \"uid\": \"85a562078cdf77779eaa1add43ccec1e\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-k8s-resources-namespace\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    k8s-resources-node.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true,\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          }\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"max capacity\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"red\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.stacking\",\n                                      \"value\": {\n                                          \"mode\": \"none\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.hideFrom\",\n                                      \"value\": {\n                                          \"legend\": false,\n                                          \"tooltip\": true,\n                                          \"viz\": false\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"dash\": [\n                                              10,\n                                              10\n                                          ],\n                                          \"fill\": \"dash\"\n                                      }\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_node_status_capacity{cluster=\\\"$cluster\\\", job=\\\"kube-state-metrics\\\", node=~\\\"$node\\\", resource=\\\"cpu\\\"})\",\n                          \"legendFormat\": \"max capacity\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", node=~\\\"$node\\\"}) by (pod)\",\n                          \"legendFormat\": \"{{pod}}\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Pod\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 6\n                  },\n                  \"id\": 2,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", node=~\\\"$node\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\\\"$cluster\\\", node=~\\\"$node\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", node=~\\\"$node\\\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\\\"$cluster\\\", node=~\\\"$node\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\\\"$cluster\\\", node=~\\\"$node\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", node=~\\\"$node\\\"}) by (pod) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\\\"$cluster\\\", node=~\\\"$node\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"pod\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"CPU Usage\",\n                                  \"Value #B\": \"CPU Requests\",\n                                  \"Value #C\": \"CPU Requests %\",\n                                  \"Value #D\": \"CPU Limits\",\n                                  \"Value #E\": \"CPU Limits %\",\n                                  \"pod\": \"Pod\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true,\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"max capacity\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"red\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.stacking\",\n                                      \"value\": {\n                                          \"mode\": \"none\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.hideFrom\",\n                                      \"value\": {\n                                          \"legend\": false,\n                                          \"tooltip\": true,\n                                          \"viz\": false\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"dash\": [\n                                              10,\n                                              10\n                                          ],\n                                          \"fill\": \"dash\"\n                                      }\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 12\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_node_status_capacity{cluster=\\\"$cluster\\\", job=\\\"kube-state-metrics\\\", node=~\\\"$node\\\", resource=\\\"memory\\\"})\",\n                          \"legendFormat\": \"max capacity\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\\\"$cluster\\\", node=~\\\"$node\\\", container!=\\\"\\\"}) by (pod)\",\n                          \"legendFormat\": \"{{pod}}\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage (w/cache)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true,\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"max capacity\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"red\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.stacking\",\n                                      \"value\": {\n                                          \"mode\": \"none\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.hideFrom\",\n                                      \"value\": {\n                                          \"legend\": false,\n                                          \"tooltip\": true,\n                                          \"viz\": false\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"dash\": [\n                                              10,\n                                              10\n                                          ],\n                                          \"fill\": \"dash\"\n                                      }\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 18\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_node_status_capacity{cluster=\\\"$cluster\\\", job=\\\"kube-state-metrics\\\", node=~\\\"$node\\\", resource=\\\"memory\\\"})\",\n                          \"legendFormat\": \"max capacity\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_memory_rss{cluster=\\\"$cluster\\\", node=~\\\"$node\\\", container!=\\\"\\\"}) by (pod)\",\n                          \"legendFormat\": \"{{pod}}\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage (w/o cache)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Pod\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 6,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 24\n                  },\n                  \"id\": 5,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\\\"$cluster\\\", node=~\\\"$node\\\",container!=\\\"\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\\\"$cluster\\\", node=~\\\"$node\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\\\"$cluster\\\", node=~\\\"$node\\\",container!=\\\"\\\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\\\"$cluster\\\", node=~\\\"$node\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\\\"$cluster\\\", node=~\\\"$node\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_memory_working_set_bytes{cluster=\\\"$cluster\\\", node=~\\\"$node\\\",container!=\\\"\\\"}) by (pod) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\\\"$cluster\\\", node=~\\\"$node\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_memory_rss{cluster=\\\"$cluster\\\", node=~\\\"$node\\\",container!=\\\"\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_memory_cache{cluster=\\\"$cluster\\\", node=~\\\"$node\\\",container!=\\\"\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_memory_swap{cluster=\\\"$cluster\\\", node=~\\\"$node\\\",container!=\\\"\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"pod\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true,\n                                  \"Time 7\": true,\n                                  \"Time 8\": true\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Memory Usage\",\n                                  \"Value #B\": \"Memory Requests\",\n                                  \"Value #C\": \"Memory Requests %\",\n                                  \"Value #D\": \"Memory Limits\",\n                                  \"Value #E\": \"Memory Limits %\",\n                                  \"Value #F\": \"Memory Usage (RSS)\",\n                                  \"Value #G\": \"Memory Usage (Cache)\",\n                                  \"Value #H\": \"Memory Usage (Swap)\",\n                                  \"pod\": \"Pod\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kube-state-metrics\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"node\",\n                      \"multi\": true,\n                      \"name\": \"node\",\n                      \"query\": \"label_values(kube_node_info{cluster=\\\"$cluster\\\"}, node)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Compute Resources / Node (Pods)\",\n          \"uid\": \"200ac8fdbfbb74b39aff88118e4d1c2c\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-k8s-resources-node\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    k8s-resources-pod.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          }\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"B\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"fill\": \"dash\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineWidth\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"red\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"C\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"fill\": \"dash\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineWidth\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"orange\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", cluster=\\\"$cluster\\\", container!=\\\"\\\"}) by (container)\",\n                          \"legendFormat\": \"__auto\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", resource=\\\"cpu\\\"}\\n)\\n\",\n                          \"legendFormat\": \"requests\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", resource=\\\"cpu\\\"}\\n)\\n\",\n                          \"legendFormat\": \"limits\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"axisColorMode\": \"thresholds\",\n                              \"axisSoftMax\": 1,\n                              \"axisSoftMin\": 0,\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true,\n                              \"thresholdsStyle\": {\n                                  \"mode\": \"dashed+area\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"A\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"thresholds\",\n                                      \"value\": {\n                                          \"mode\": \"absolute\",\n                                          \"steps\": [\n                                              {\n                                                  \"color\": \"green\",\n                                                  \"value\": null\n                                              },\n                                              {\n                                                  \"color\": \"red\",\n                                                  \"value\": 0.25\n                                              }\n                                          ]\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"mode\": \"thresholds\",\n                                          \"seriesBy\": \"lastNotNull\"\n                                      }\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(increase(container_cpu_cfs_throttled_periods_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\"}[$__rate_interval])) by (container) /sum(increase(container_cpu_cfs_periods_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\"}[$__rate_interval])) by (container)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"CPU Throttling\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 3,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container!=\\\"\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container!=\\\"\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container!=\\\"\\\"}) by (container) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container!=\\\"\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container!=\\\"\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container!=\\\"\\\"}) by (container) / sum(cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container!=\\\"\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"container\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Value #A\": 6,\n                                  \"Value #B\": 7,\n                                  \"Value #C\": 8,\n                                  \"Value #D\": 9,\n                                  \"Value #E\": 10,\n                                  \"container\": 5\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"CPU Usage\",\n                                  \"Value #B\": \"CPU Requests\",\n                                  \"Value #C\": \"CPU Requests %\",\n                                  \"Value #D\": \"CPU Limits\",\n                                  \"Value #E\": \"CPU Limits %\",\n                                  \"container\": \"Container\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"B\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"fill\": \"dash\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineWidth\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"red\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"C\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"fill\": \"dash\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineWidth\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"orange\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container!=\\\"\\\", image!=\\\"\\\"}) by (container)\",\n                          \"legendFormat\": \"__auto\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", resource=\\\"memory\\\"}\\n)\\n\",\n                          \"legendFormat\": \"requests\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", resource=\\\"memory\\\"}\\n)\\n\",\n                          \"legendFormat\": \"limits\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage (WSS)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 28\n                  },\n                  \"id\": 5,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container!=\\\"\\\", image!=\\\"\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", image!=\\\"\\\"}) by (container) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container!=\\\"\\\", image!=\\\"\\\"}) by (container) / sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_limits{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_rss{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container != \\\"\\\", container != \\\"POD\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_cache{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container != \\\"\\\", container != \\\"POD\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(container_memory_swap{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\", container != \\\"\\\", container != \\\"POD\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"container\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true,\n                                  \"Time 7\": true,\n                                  \"Time 8\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Time 7\": 6,\n                                  \"Time 8\": 7,\n                                  \"Value #A\": 9,\n                                  \"Value #B\": 10,\n                                  \"Value #C\": 11,\n                                  \"Value #D\": 12,\n                                  \"Value #E\": 13,\n                                  \"Value #F\": 14,\n                                  \"Value #G\": 15,\n                                  \"Value #H\": 16,\n                                  \"container\": 8\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Memory Usage\",\n                                  \"Value #B\": \"Memory Requests\",\n                                  \"Value #C\": \"Memory Requests %\",\n                                  \"Value #D\": \"Memory Limits\",\n                                  \"Value #E\": \"Memory Limits %\",\n                                  \"Value #F\": \"Memory Usage (RSS)\",\n                                  \"Value #G\": \"Memory Usage (Cache)\",\n                                  \"Value #H\": \"Memory Usage (Swap)\",\n                                  \"container\": \"Container\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 35\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(irate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Receive Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 35\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Transmit Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 42\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 42\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 49\n                  },\n                  \"id\": 10,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 49\n                  },\n                  \"id\": 11,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"iops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 56\n                  },\n                  \"id\": 12,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"ceil(sum by(pod) (rate(container_fs_reads_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])))\",\n                          \"legendFormat\": \"Reads\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"ceil(sum by(pod) (rate(container_fs_writes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])))\",\n                          \"legendFormat\": \"Writes\"\n                      }\n                  ],\n                  \"title\": \"IOPS (Pod)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 56\n                  },\n                  \"id\": 13,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(pod) (rate(container_fs_reads_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"Reads\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(pod) (rate(container_fs_writes_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"Writes\"\n                      }\n                  ],\n                  \"title\": \"ThroughPut (Pod)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"iops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 63\n                  },\n                  \"id\": 14,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"ceil(sum by(container) (rate(container_fs_reads_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval])))\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"IOPS (Containers)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 63\n                  },\n                  \"id\": 15,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(container) (rate(container_fs_reads_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"ThroughPut (Containers)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/IOPS/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"iops\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Throughput/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"Bps\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 70\n                  },\n                  \"id\": 16,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(container) (rate(container_fs_reads_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(container) (rate(container_fs_writes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\",device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(container) (rate(container_fs_reads_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval]) + rate(container_fs_writes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(container) (rate(container_fs_reads_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(container) (rate(container_fs_writes_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by(container) (rate(container_fs_reads_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval]) + rate(container_fs_writes_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\", container!=\\\"\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval]))\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Current Storage IO\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"container\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Value #A\": 7,\n                                  \"Value #B\": 8,\n                                  \"Value #C\": 9,\n                                  \"Value #D\": 10,\n                                  \"Value #E\": 11,\n                                  \"Value #F\": 12,\n                                  \"container\": 6\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"IOPS(Reads)\",\n                                  \"Value #B\": \"IOPS(Writes)\",\n                                  \"Value #C\": \"IOPS(Reads + Writes)\",\n                                  \"Value #D\": \"Throughput(Read)\",\n                                  \"Value #E\": \"Throughput(Write)\",\n                                  \"Value #F\": \"Throughput(Read + Write)\",\n                                  \"container\": \"Container\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kube-state-metrics\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"namespace\",\n                      \"name\": \"namespace\",\n                      \"query\": \"label_values(kube_namespace_status_phase{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\"}, namespace)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"pod\",\n                      \"name\": \"pod\",\n                      \"query\": \"label_values(kube_pod_info{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}, pod)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Compute Resources / Pod\",\n          \"uid\": \"6581e46e4e5c7ba40a07646395ef7b23\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-k8s-resources-pod\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    k8s-resources-windows-cluster.json: |-\n      {\n          \"editable\": false,\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"1 - avg(rate(windows_cpu_time_total{cluster=\\\"$cluster\\\", job=\\\"kubernetes-windows-exporter\\\", mode=\\\"idle\\\"}[$__rate_interval]))\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Utilisation\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 4,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\\\"$cluster\\\"}) / sum(node:windows_node_num_cpu:sum{cluster=\\\"$cluster\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Requests Commitment\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 8,\n                      \"y\": 0\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\\\"$cluster\\\"}) / sum(node:windows_node_num_cpu:sum{cluster=\\\"$cluster\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Limits Commitment\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 12,\n                      \"y\": 0\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"1 - sum(:windows_node_memory_MemFreeCached_bytes:sum{cluster=\\\"$cluster\\\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\\\"$cluster\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Utilisation\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 16,\n                      \"y\": 0\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_memory_request{cluster=\\\"$cluster\\\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\\\"$cluster\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Requests Commitment\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 3,\n                      \"w\": 4,\n                      \"x\": 20,\n                      \"y\": 0\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_memory_limit{cluster=\\\"$cluster\\\"}) / sum(:windows_node_memory_MemTotal_bytes:sum{cluster=\\\"$cluster\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Limits Commitment\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          }\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Namespace\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 8,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\\\"$cluster\\\"}) by (namespace) / sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\\\"$cluster\\\"}) by (namespace) / sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"namespace\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Value #A\": 6,\n                                  \"Value #B\": 7,\n                                  \"Value #C\": 8,\n                                  \"Value #D\": 9,\n                                  \"Value #E\": 10,\n                                  \"namespace\": 5\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"CPU Usage\",\n                                  \"Value #B\": \"CPU Requests\",\n                                  \"Value #C\": \"CPU Requests %\",\n                                  \"Value #D\": \"CPU Limits\",\n                                  \"Value #E\": \"CPU Limits %\",\n                                  \"namespace\": \"Namespace\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"decbytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(windows_container_private_working_set_usage{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage (Private Working Set)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Memory Usage\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"decbytes\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Memory Requests\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"decbytes\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Memory Limits\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"decbytes\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Namespace\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 28\n                  },\n                  \"id\": 10,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(windows_container_private_working_set_usage{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_memory_request{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(windows_container_private_working_set_usage{cluster=\\\"$cluster\\\"}) by (namespace) / sum(kube_pod_windows_container_resource_memory_request{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_memory_limit{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(windows_container_private_working_set_usage{cluster=\\\"$cluster\\\"}) by (namespace) / sum(kube_pod_windows_container_resource_memory_limit{cluster=\\\"$cluster\\\"}) by (namespace)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Requests by Namespace\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"namespace\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Value #A\": 6,\n                                  \"Value #B\": 7,\n                                  \"Value #C\": 8,\n                                  \"Value #D\": 9,\n                                  \"Value #E\": 10,\n                                  \"namespace\": 5\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Memory Usage\",\n                                  \"Value #B\": \"Memory Requests\",\n                                  \"Value #C\": \"Memory Requests %\",\n                                  \"Value #D\": \"Memory Limits\",\n                                  \"Value #E\": \"Memory Limits %\",\n                                  \"namespace\": \"Namespace\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kubernetes-windows-exporter\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Kubernetes / Compute Resources / Cluster(Windows)\",\n          \"uid\": \"4d08557fd9391b100730f2494bccac68\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-k8s-resources-windows-cluster\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    k8s-resources-windows-namespace.json: |-\n      {\n          \"editable\": false,\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          }\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Pod\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/40597a704a610e936dc6ed374a7ce023/k8s-resources-windows-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 2,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod) / sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod) / sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"pod\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Value #A\": 6,\n                                  \"Value #B\": 7,\n                                  \"Value #C\": 8,\n                                  \"Value #D\": 9,\n                                  \"Value #E\": 10,\n                                  \"pod\": 5\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"CPU Usage\",\n                                  \"Value #B\": \"CPU Requests\",\n                                  \"Value #C\": \"CPU Requests %\",\n                                  \"Value #D\": \"CPU Limits\",\n                                  \"Value #E\": \"CPU Limits %\",\n                                  \"pod\": \"Pod\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"decbytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(windows_container_private_working_set_usage{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage (Private Working Set)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Pod\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/40597a704a610e936dc6ed374a7ce023/k8s-resources-windows-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 4,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(windows_container_private_working_set_usage{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_memory_request{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(windows_container_private_working_set_usage{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod) / sum(kube_pod_windows_container_resource_memory_request{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_memory_limit{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(windows_container_private_working_set_usage{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod) / sum(kube_pod_windows_container_resource_memory_limit{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}) by (pod)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"pod\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Value #A\": 6,\n                                  \"Value #B\": 7,\n                                  \"Value #C\": 8,\n                                  \"Value #D\": 9,\n                                  \"Value #E\": 10,\n                                  \"pod\": 5\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Memory Usage\",\n                                  \"Value #B\": \"Memory Requests\",\n                                  \"Value #C\": \"Memory Requests %\",\n                                  \"Value #D\": \"Memory Limits\",\n                                  \"Value #E\": \"Memory Limits %\",\n                                  \"pod\": \"Pod\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kubernetes-windows-exporter\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"namespace\",\n                      \"name\": \"namespace\",\n                      \"query\": \"label_values(windows_pod_container_available{cluster=\\\"$cluster\\\"}, namespace)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Kubernetes / Compute Resources / Namespace(Windows)\",\n          \"uid\": \"490b402361724ab1d4c45666c1fa9b6f\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-k8s-resources-windows-namespace\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    k8s-resources-windows-pod.json: |-\n      {\n          \"editable\": false,\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          }\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Namespace\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/490b402361724ab1d4c45666c1fa9b6f/k8s-resources-windows-namespace?${datasource:queryparam}&var-cluster=$cluster&var-namespace=${__data.fields.Namespace}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 2,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container) / sum(kube_pod_windows_container_resource_cpu_cores_request{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(namespace_pod_container:windows_container_cpu_usage_seconds_total:sum_rate{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container) / sum(kube_pod_windows_container_resource_cpu_cores_limit{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"container\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Value #A\": 6,\n                                  \"Value #B\": 7,\n                                  \"Value #C\": 8,\n                                  \"Value #D\": 9,\n                                  \"Value #E\": 10,\n                                  \"container\": 5\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"CPU Usage\",\n                                  \"Value #B\": \"CPU Requests\",\n                                  \"Value #C\": \"CPU Requests %\",\n                                  \"Value #D\": \"CPU Limits\",\n                                  \"Value #E\": \"CPU Limits %\",\n                                  \"container\": \"Container\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"decbytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(windows_container_private_working_set_usage{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 4,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(windows_container_private_working_set_usage{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_memory_request{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(windows_container_private_working_set_usage{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container) / sum(kube_pod_windows_container_resource_memory_request{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kube_pod_windows_container_resource_memory_limit{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(windows_container_private_working_set_usage{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container) / sum(kube_pod_windows_container_resource_memory_limit{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}) by (container)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"container\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Value #A\": 6,\n                                  \"Value #B\": 7,\n                                  \"Value #C\": 8,\n                                  \"Value #D\": 9,\n                                  \"Value #E\": 10,\n                                  \"container\": 5\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Memory Usage\",\n                                  \"Value #B\": \"Memory Requests\",\n                                  \"Value #C\": \"Memory Requests %\",\n                                  \"Value #D\": \"Memory Limits\",\n                                  \"Value #E\": \"Memory Limits %\",\n                                  \"container\": \"Container\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 28\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum by (container) (rate(windows_container_network_received_bytes_total{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval])))\",\n                          \"legendFormat\": \"Received : {{ container }}\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum by (container) (rate(windows_container_network_transmitted_bytes_total{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", pod=\\\"$pod\\\"}[$__rate_interval])))\",\n                          \"legendFormat\": \"Transmitted : {{ container }}\"\n                      }\n                  ],\n                  \"title\": \"Network I/O\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kubernetes-windows-exporter\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"namespace\",\n                      \"name\": \"namespace\",\n                      \"query\": \"label_values(windows_pod_container_available{cluster=\\\"$cluster\\\"}, namespace)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"pod\",\n                      \"name\": \"pod\",\n                      \"query\": \"label_values(windows_pod_container_available{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}, pod)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Kubernetes / Compute Resources / Pod(Windows)\",\n          \"uid\": \"40597a704a610e936dc6ed374a7ce023\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-k8s-resources-windows-pod\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    k8s-resources-workload.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          }\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Pod\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 2,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"cpu\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n/sum(\\n    kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"cpu\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"cpu\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n/sum(\\n    kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"cpu\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"pod\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Value #A\": 6,\n                                  \"Value #B\": 7,\n                                  \"Value #C\": 8,\n                                  \"Value #D\": 9,\n                                  \"Value #E\": 10,\n                                  \"pod\": 5\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"CPU Usage\",\n                                  \"Value #B\": \"CPU Requests\",\n                                  \"Value #C\": \"CPU Requests %\",\n                                  \"Value #D\": \"CPU Limits\",\n                                  \"Value #E\": \"CPU Limits %\",\n                                  \"pod\": \"Pod\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    container_memory_working_set_bytes{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", container!=\\\"\\\", image!=\\\"\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Pod\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 4,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    container_memory_working_set_bytes{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", container!=\\\"\\\", image!=\\\"\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"memory\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    container_memory_working_set_bytes{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", container!=\\\"\\\", image!=\\\"\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n/sum(\\n    kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"memory\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"memory\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    container_memory_working_set_bytes{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", container!=\\\"\\\", image!=\\\"\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n/sum(\\n    kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"memory\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=\\\"$workload\\\", workload_type=~\\\"$type\\\"}\\n) by (pod)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"pod\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Value #A\": 9,\n                                  \"Value #B\": 10,\n                                  \"Value #C\": 11,\n                                  \"Value #D\": 12,\n                                  \"Value #E\": 13,\n                                  \"pod\": 8\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Memory Usage\",\n                                  \"Value #B\": \"Memory Requests\",\n                                  \"Value #C\": \"Memory Requests %\",\n                                  \"Value #D\": \"Memory Limits\",\n                                  \"Value #E\": \"Memory Limits %\",\n                                  \"pod\": \"Pod\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Bandwidth/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"Bps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Packets/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"pps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Pod\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to pods\",\n                                              \"url\": \"/d/6581e46e4e5c7ba40a07646395ef7b23/k8s-resources-pod?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-pod=${__data.fields.Pod}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 28\n                  },\n                  \"id\": 5,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_receive_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_transmit_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_receive_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_transmit_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Current Network Usage\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"pod\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Value #A\": 7,\n                                  \"Value #B\": 8,\n                                  \"Value #C\": 9,\n                                  \"Value #D\": 10,\n                                  \"Value #E\": 11,\n                                  \"Value #F\": 12,\n                                  \"pod\": 6\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Current Receive Bandwidth\",\n                                  \"Value #B\": \"Current Transmit Bandwidth\",\n                                  \"Value #C\": \"Rate of Received Packets\",\n                                  \"Value #D\": \"Rate of Transmitted Packets\",\n                                  \"Value #E\": \"Rate of Received Packets Dropped\",\n                                  \"Value #F\": \"Rate of Transmitted Packets Dropped\",\n                                  \"pod\": \"Pod\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 35\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Receive Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 35\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Transmit Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 42\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(avg(rate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Average Container Bandwidth by Pod: Received\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 42\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(avg(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Average Container Bandwidth by Pod: Transmitted\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 49\n                  },\n                  \"id\": 10,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_receive_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 49\n                  },\n                  \"id\": 11,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_transmit_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 56\n                  },\n                  \"id\": 12,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_receive_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 56\n                  },\n                  \"id\": 13,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_transmit_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets Dropped\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kube-state-metrics\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"namespace\",\n                      \"name\": \"namespace\",\n                      \"query\": \"label_values(kube_namespace_status_phase{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\"}, namespace)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": \"workload_type\",\n                      \"name\": \"type\",\n                      \"query\": \"label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}, workload_type)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"workload\",\n                      \"name\": \"workload\",\n                      \"query\": \"label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}, workload)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Compute Resources / Workload\",\n          \"uid\": \"a164a7f0339f99e89cea5cb47e9be617\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-k8s-resources-workload\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    k8s-resources-workloads-namespace.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          }\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"B\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"fill\": \"dash\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineWidth\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"red\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"C\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"fill\": \"dash\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineWidth\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"orange\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n  node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}\\n* on(namespace,pod)\\n  group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n\",\n                          \"legendFormat\": \"{{workload}} - {{workload_type}}\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"scalar(max(kube_resourcequota{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", type=\\\"hard\\\",resource=~\\\"requests.cpu|cpu\\\"}))\",\n                          \"legendFormat\": \"quota - requests\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"scalar(max(kube_resourcequota{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", type=\\\"hard\\\",resource=~\\\"limits.cpu\\\"}))\",\n                          \"legendFormat\": \"quota - limits\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Workload\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to workloads\",\n                                              \"url\": \"/d/a164a7f0339f99e89cea5cb47e9be617/k8s-resources-workload?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-type=${__data.fields.Type}&var-workload=${__data.fields.Workload}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Running Pods\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"none\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 2,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"count(namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}) by (workload, workload_type)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n  node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}\\n* on(namespace,pod)\\n  group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n  kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"cpu\\\"}\\n* on(namespace,pod)\\n  group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n  node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}\\n* on(namespace,pod)\\n  group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n/sum(\\n  kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"cpu\\\"}\\n* on(namespace,pod)\\n  group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n  kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"cpu\\\"}\\n* on(namespace,pod)\\n  group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n  node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}\\n* on(namespace,pod)\\n  group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n/sum(\\n  kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"cpu\\\"}\\n* on(namespace,pod)\\n  group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"CPU Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"workload\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true,\n                                  \"workload_type 2\": true,\n                                  \"workload_type 3\": true,\n                                  \"workload_type 4\": true,\n                                  \"workload_type 5\": true,\n                                  \"workload_type 6\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Value #A\": 8,\n                                  \"Value #B\": 9,\n                                  \"Value #C\": 10,\n                                  \"Value #D\": 11,\n                                  \"Value #E\": 12,\n                                  \"Value #F\": 13,\n                                  \"workload\": 6,\n                                  \"workload_type 1\": 7,\n                                  \"workload_type 2\": 14,\n                                  \"workload_type 3\": 15,\n                                  \"workload_type 4\": 16,\n                                  \"workload_type 5\": 17,\n                                  \"workload_type 6\": 18\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Running Pods\",\n                                  \"Value #B\": \"CPU Usage\",\n                                  \"Value #C\": \"CPU Requests\",\n                                  \"Value #D\": \"CPU Requests %\",\n                                  \"Value #E\": \"CPU Limits\",\n                                  \"Value #F\": \"CPU Limits %\",\n                                  \"workload\": \"Workload\",\n                                  \"workload_type 1\": \"Type\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"B\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"fill\": \"dash\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineWidth\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"red\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byFrameRefID\",\n                                  \"options\": \"C\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.lineStyle\",\n                                      \"value\": {\n                                          \"fill\": \"dash\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"custom.lineWidth\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"color\",\n                                      \"value\": {\n                                          \"fixedColor\": \"orange\",\n                                          \"mode\": \"fixed\"\n                                      }\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", container!=\\\"\\\", image!=\\\"\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n\",\n                          \"legendFormat\": \"{{workload}} - {{workload_type}}\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"scalar(max(kube_resourcequota{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", type=\\\"hard\\\",resource=~\\\"requests.memory|memory\\\"}))\",\n                          \"legendFormat\": \"quota - requests\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"scalar(max(kube_resourcequota{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", type=\\\"hard\\\",resource=~\\\"limits.memory\\\"}))\",\n                          \"legendFormat\": \"quota - limits\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/%/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Workload\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to workloads\",\n                                              \"url\": \"/d/a164a7f0339f99e89cea5cb47e9be617/k8s-resources-workload?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-type=${__data.fields.Type}&var-workload=${__data.fields.Workload}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Running Pods\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"none\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 4,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"count(namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}) by (workload, workload_type)\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", container!=\\\"\\\", image!=\\\"\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n  kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"memory\\\"}\\n* on(namespace,pod)\\n  group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", container!=\\\"\\\", image!=\\\"\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n/sum(\\n  kube_pod_container_resource_requests{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"memory\\\"}\\n* on(namespace,pod)\\n  group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n  kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"memory\\\"}\\n* on(namespace,pod)\\n  group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(\\n    container_memory_working_set_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", container!=\\\"\\\", image!=\\\"\\\"}\\n  * on(namespace,pod)\\n    group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n/sum(\\n  kube_pod_container_resource_limits{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", resource=\\\"memory\\\"}\\n* on(namespace,pod)\\n  group_left(workload, workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}\\n) by (workload, workload_type)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Memory Quota\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"workload\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true,\n                                  \"workload_type 2\": true,\n                                  \"workload_type 3\": true,\n                                  \"workload_type 4\": true,\n                                  \"workload_type 5\": true,\n                                  \"workload_type 6\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Value #A\": 8,\n                                  \"Value #B\": 9,\n                                  \"Value #C\": 10,\n                                  \"Value #D\": 11,\n                                  \"Value #E\": 12,\n                                  \"Value #F\": 13,\n                                  \"workload\": 6,\n                                  \"workload_type 1\": 7,\n                                  \"workload_type 2\": 14,\n                                  \"workload_type 3\": 15,\n                                  \"workload_type 4\": 16,\n                                  \"workload_type 5\": 17,\n                                  \"workload_type 6\": 18\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Running Pods\",\n                                  \"Value #B\": \"Memory Usage\",\n                                  \"Value #C\": \"Memory Requests\",\n                                  \"Value #D\": \"Memory Requests %\",\n                                  \"Value #E\": \"Memory Limits\",\n                                  \"Value #F\": \"Memory Limits %\",\n                                  \"workload\": \"Workload\",\n                                  \"workload_type 1\": \"Type\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Bandwidth/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"Bps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Packets/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"pps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Workload\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down to workloads\",\n                                              \"url\": \"/d/a164a7f0339f99e89cea5cb47e9be617/k8s-resources-workload?${datasource:queryparam}&var-cluster=$cluster&var-namespace=$namespace&var-type=${__data.fields.Type}&var-workload=${__data.fields.Workload}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 28\n                  },\n                  \"id\": 5,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_receive_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_transmit_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_receive_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_transmit_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Current Network Usage\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"workload\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Value #A\": 7,\n                                  \"Value #B\": 8,\n                                  \"Value #C\": 9,\n                                  \"Value #D\": 10,\n                                  \"Value #E\": 11,\n                                  \"Value #F\": 12,\n                                  \"workload\": 6\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Current Receive Bandwidth\",\n                                  \"Value #B\": \"Current Transmit Bandwidth\",\n                                  \"Value #C\": \"Rate of Received Packets\",\n                                  \"Value #D\": \"Rate of Transmitted Packets\",\n                                  \"Value #E\": \"Rate of Received Packets Dropped\",\n                                  \"Value #F\": \"Rate of Transmitted Packets Dropped\",\n                                  \"workload\": \"Workload\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 35\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Receive Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 35\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Transmit Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 42\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(avg(rate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Average Container Bandwidth by Workload: Received\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 42\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(avg(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Average Container Bandwidth by Workload: Transmitted\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 49\n                  },\n                  \"id\": 10,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_receive_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 49\n                  },\n                  \"id\": 11,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_transmit_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 56\n                  },\n                  \"id\": 12,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_receive_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 56\n                  },\n                  \"id\": 13,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(sum(rate(container_network_transmit_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets Dropped\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kube-state-metrics\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"namespace\",\n                      \"name\": \"namespace\",\n                      \"query\": \"label_values(kube_namespace_status_phase{job=\\\"kube-state-metrics\\\", cluster=\\\"$cluster\\\"}, namespace)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": \"workload_type\",\n                      \"name\": \"type\",\n                      \"query\": \"label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\".+\\\"}, workload_type)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Compute Resources / Namespace (Workloads)\",\n          \"uid\": \"a87fb0d919ec0ea5f6543124e16c42a5\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-k8s-resources-workloads-namespace\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    k8s-windows-cluster-rsrc-use.json: |-\n      {\n          \"editable\": false,\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_cpu_utilisation:avg1m{cluster=\\\"$cluster\\\"} * node:windows_node_num_cpu:sum{cluster=\\\"$cluster\\\"} / scalar(sum(node:windows_node_num_cpu:sum{cluster=\\\"$cluster\\\"}))\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"CPU Utilisation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_memory_utilisation:ratio{cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Memory Utilisation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 7\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_memory_swap_io_pages:irate{cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Memory Saturation (Swap I/O Pages)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_disk_utilisation:avg_irate{cluster=\\\"$cluster\\\"} / scalar(node:windows_node:sum{cluster=\\\"$cluster\\\"})\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Disk IO Utilisation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_net_utilisation:sum_irate{cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Net Utilisation (Transmitted)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 21\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_net_saturation:sum_irate{cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Net Utilisation (Dropped)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 28\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (instance)(node:windows_node_filesystem_usage:{cluster=\\\"$cluster\\\"})\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Disk Capacity\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kubernetes-windows-exporter\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Kubernetes / USE Method / Cluster(Windows)\",\n          \"uid\": \"53a43377ec9aaf2ff64dfc7a1f539334\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-k8s-windows-cluster-rsrc-use\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    k8s-windows-node-rsrc-use.json: |-\n      {\n          \"editable\": false,\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_cpu_utilisation:avg1m{cluster=\\\"$cluster\\\", instance=\\\"$instance\\\"}\",\n                          \"legendFormat\": \"Utilisation\"\n                      }\n                  ],\n                  \"title\": \"CPU Utilisation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (core) (irate(windows_cpu_time_total{cluster=\\\"$cluster\\\", job=\\\"kubernetes-windows-exporter\\\", mode!=\\\"idle\\\", instance=\\\"$instance\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"{{core}}\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage Per Core\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_memory_utilisation:{cluster=\\\"$cluster\\\", instance=\\\"$instance\\\"}\",\n                          \"legendFormat\": \"Memory\"\n                      }\n                  ],\n                  \"title\": \"Memory Utilisation %\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 8,\n                      \"y\": 7\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"max(\\n  windows_os_visible_memory_bytes{cluster=\\\"$cluster\\\", job=\\\"kubernetes-windows-exporter\\\", instance=\\\"$instance\\\"}\\n  - windows_memory_available_bytes{cluster=\\\"$cluster\\\", job=\\\"kubernetes-windows-exporter\\\", instance=\\\"$instance\\\"}\\n)\\n\",\n                          \"legendFormat\": \"memory used\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"max(node:windows_node_memory_totalCached_bytes:sum{cluster=\\\"$cluster\\\", instance=\\\"$instance\\\"})\",\n                          \"legendFormat\": \"memory cached\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"max(windows_memory_available_bytes{cluster=\\\"$cluster\\\", job=\\\"kubernetes-windows-exporter\\\", instance=\\\"$instance\\\"})\",\n                          \"legendFormat\": \"memory free\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 16,\n                      \"y\": 7\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_memory_swap_io_pages:irate{cluster=\\\"$cluster\\\", instance=\\\"$instance\\\"}\",\n                          \"legendFormat\": \"Swap IO\"\n                      }\n                  ],\n                  \"title\": \"Memory Saturation (Swap I/O) Pages\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_disk_utilisation:avg_irate{cluster=\\\"$cluster\\\", instance=\\\"$instance\\\"}\",\n                          \"legendFormat\": \"Utilisation\"\n                      }\n                  ],\n                  \"title\": \"Disk IO Utilisation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/io time/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"ms\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 14\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"max(rate(windows_logical_disk_read_bytes_total{cluster=\\\"$cluster\\\", job=\\\"kubernetes-windows-exporter\\\", instance=\\\"$instance\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"read\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"max(rate(windows_logical_disk_write_bytes_total{cluster=\\\"$cluster\\\", job=\\\"kubernetes-windows-exporter\\\", instance=\\\"$instance\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"written\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"max(rate(windows_logical_disk_read_seconds_total{cluster=\\\"$cluster\\\", job=\\\"kubernetes-windows-exporter\\\",  instance=\\\"$instance\\\"}[$__rate_interval]) + rate(windows_logical_disk_write_seconds_total{cluster=\\\"$cluster\\\", job=\\\"kubernetes-windows-exporter\\\", instance=\\\"$instance\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"io time\"\n                      }\n                  ],\n                  \"title\": \"Disk IO\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_filesystem_usage:{cluster=\\\"$cluster\\\", instance=\\\"$instance\\\"}\",\n                          \"legendFormat\": \"{{volume}}\"\n                      }\n                  ],\n                  \"title\": \"Disk Utilisation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 28\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_net_utilisation:sum_irate{cluster=\\\"$cluster\\\", instance=\\\"$instance\\\"}\",\n                          \"legendFormat\": \"Utilisation\"\n                      }\n                  ],\n                  \"title\": \"Net Utilisation (Transmitted)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 28\n                  },\n                  \"id\": 10,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"node:windows_node_net_saturation:sum_irate{cluster=\\\"$cluster\\\", instance=\\\"$instance\\\"}\",\n                          \"legendFormat\": \"Saturation\"\n                      }\n                  ],\n                  \"title\": \"Net Saturation (Dropped)\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kubernetes-windows-exporter\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"instance\",\n                      \"name\": \"instance\",\n                      \"query\": \"label_values(windows_system_boot_time_timestamp_seconds{cluster=\\\"$cluster\\\"}, instance)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Kubernetes / USE Method / Node(Windows)\",\n          \"uid\": \"96e7484b0bb53b74fbc2bcb7723cd40b\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-k8s-windows-node-rsrc-use\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    kubelet.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 4,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kubelet_node_name{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Running Kubelets\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 4,\n                      \"x\": 4,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kubelet_running_pods{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Running Pods\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 4,\n                      \"x\": 8,\n                      \"y\": 0\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(kubelet_running_containers{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Running Containers\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 4,\n                      \"x\": 12,\n                      \"y\": 0\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(volume_manager_total_volumes{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\", state=\\\"actual_state_of_world\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Actual Volume Count\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 4,\n                      \"x\": 16,\n                      \"y\": 0\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(volume_manager_total_volumes{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\",state=\\\"desired_state_of_world\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Desired Volume Count\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 4,\n                      \"x\": 20,\n                      \"y\": 0\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(kubelet_node_config_error{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\"}[$__rate_interval]))\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Config Error Count\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(kubelet_runtime_operations_total{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (operation_type, instance)\",\n                          \"legendFormat\": \"{{instance}} {{operation_type}}\"\n                      }\n                  ],\n                  \"title\": \"Operation Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 7\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(kubelet_runtime_operations_errors_total{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, operation_type)\",\n                          \"legendFormat\": \"{{instance}} {{operation_type}}\"\n                      }\n                  ],\n                  \"title\": \"Operation Error Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(kubelet_runtime_operations_duration_seconds_bucket{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, operation_type, le))\",\n                          \"legendFormat\": \"{{instance}} {{operation_type}}\"\n                      }\n                  ],\n                  \"title\": \"Operation Duration 99th quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 10,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(kubelet_pod_start_duration_seconds_count{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance)\",\n                          \"legendFormat\": \"{{instance}} pod\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(kubelet_pod_worker_duration_seconds_count{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance)\",\n                          \"legendFormat\": \"{{instance}} worker\"\n                      }\n                  ],\n                  \"title\": \"Pod Start Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 21\n                  },\n                  \"id\": 11,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(kubelet_pod_start_duration_seconds_bucket{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, le))\",\n                          \"legendFormat\": \"{{instance}} pod\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(kubelet_pod_worker_duration_seconds_bucket{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, le))\",\n                          \"legendFormat\": \"{{instance}} worker\"\n                      }\n                  ],\n                  \"title\": \"Pod Start Duration\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 28\n                  },\n                  \"id\": 12,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(storage_operation_duration_seconds_count{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, operation_name, volume_plugin)\",\n                          \"legendFormat\": \"{{instance}} {{operation_name}} {{volume_plugin}}\"\n                      }\n                  ],\n                  \"title\": \"Storage Operation Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 28\n                  },\n                  \"id\": 13,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(storage_operation_errors_total{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, operation_name, volume_plugin)\",\n                          \"legendFormat\": \"{{instance}} {{operation_name}} {{volume_plugin}}\"\n                      }\n                  ],\n                  \"title\": \"Storage Operation Error Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 35\n                  },\n                  \"id\": 14,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(storage_operation_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, operation_name, volume_plugin, le))\",\n                          \"legendFormat\": \"{{instance}} {{operation_name}} {{volume_plugin}}\"\n                      }\n                  ],\n                  \"title\": \"Storage Operation Duration 99th quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 42\n                  },\n                  \"id\": 15,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(kubelet_cgroup_manager_duration_seconds_count{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, operation_type)\",\n                          \"legendFormat\": \"{{operation_type}}\"\n                      }\n                  ],\n                  \"title\": \"Cgroup manager operation rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 42\n                  },\n                  \"id\": 16,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(kubelet_cgroup_manager_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, operation_type, le))\",\n                          \"legendFormat\": \"{{instance}} {{operation_type}}\"\n                      }\n                  ],\n                  \"title\": \"Cgroup manager 99th quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 49\n                  },\n                  \"id\": 17,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(kubelet_pleg_relist_duration_seconds_count{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance)\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"PLEG relist rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 49\n                  },\n                  \"id\": 18,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(kubelet_pleg_relist_interval_seconds_bucket{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, le))\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"PLEG relist interval\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 56\n                  },\n                  \"id\": 19,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(kubelet_pleg_relist_duration_seconds_bucket{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, le))\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"PLEG relist duration\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 63\n                  },\n                  \"id\": 20,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\",code=~\\\"2..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"2xx\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\",code=~\\\"3..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"3xx\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\",code=~\\\"4..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"4xx\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\",code=~\\\"5..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"5xx\"\n                      }\n                  ],\n                  \"title\": \"RPC rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 70\n                  },\n                  \"id\": 21,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, verb, le))\",\n                          \"legendFormat\": \"{{instance}} {{verb}}\"\n                      }\n                  ],\n                  \"title\": \"Request duration 99th quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 0,\n                      \"y\": 77\n                  },\n                  \"id\": 22,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"process_resident_memory_bytes{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Memory\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 8,\n                      \"y\": 77\n                  },\n                  \"id\": 23,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"rate(process_cpu_seconds_total{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}[$__rate_interval])\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"CPU usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 16,\n                      \"y\": 77\n                  },\n                  \"id\": 24,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"go_goroutines{cluster=\\\"$cluster\\\",job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",instance=~\\\"$instance\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Goroutines\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": \"instance\",\n                      \"name\": \"instance\",\n                      \"query\": \"label_values(up{job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\",cluster=\\\"$cluster\\\"}, instance)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Kubelet\",\n          \"uid\": \"3138fa155d5915769fbded898ac09fd9\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-kubelet\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    namespace-by-pod.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"displayName\": \"$namespace\",\n                          \"max\": 10000000000,\n                          \"min\": 0,\n                          \"thresholds\": {\n                              \"steps\": [\n                                  {\n                                      \"color\": \"dark-green\",\n                                      \"index\": 0,\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"color\": \"dark-yellow\",\n                                      \"index\": 1,\n                                      \"value\": 5000000000\n                                  },\n                                  {\n                                      \"color\": \"dark-red\",\n                                      \"index\": 2,\n                                      \"value\": 7000000000\n                                  }\n                              ]\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum (\\n    rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Current Rate of Bytes Received\",\n                  \"type\": \"gauge\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"displayName\": \"$namespace\",\n                          \"max\": 10000000000,\n                          \"min\": 0,\n                          \"thresholds\": {\n                              \"steps\": [\n                                  {\n                                      \"color\": \"dark-green\",\n                                      \"index\": 0,\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"color\": \"dark-yellow\",\n                                      \"index\": 1,\n                                      \"value\": 5000000000\n                                  },\n                                  {\n                                      \"color\": \"dark-red\",\n                                      \"index\": 2,\n                                      \"value\": 7000000000\n                                  }\n                              ]\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum (\\n    rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Current Rate of Bytes Transmitted\",\n                  \"type\": \"gauge\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Bandwidth/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"Bps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Packets/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"pps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Pod\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down\",\n                                              \"url\": \"/d/7a18067ce943a40ae25454675c19ff5c/kubernetes-networking-pod?${datasource:queryparam}&var-cluster=${cluster}&var-namespace=${namespace}&var-pod=${__data.fields.Pod}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 3,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (pod) (\\n    rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (pod) (\\n    rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (pod) (\\n    rate(container_network_receive_packets_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (pod) (\\n    rate(container_network_transmit_packets_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (pod) (\\n    rate(container_network_receive_packets_dropped_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (pod) (\\n    rate(container_network_transmit_packets_dropped_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Current Network Usage\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"pod\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Value #A\": 7,\n                                  \"Value #B\": 8,\n                                  \"Value #C\": 9,\n                                  \"Value #D\": 10,\n                                  \"Value #E\": 11,\n                                  \"Value #F\": 12,\n                                  \"pod\": 6\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Current Receive Bandwidth\",\n                                  \"Value #B\": \"Current Transmit Bandwidth\",\n                                  \"Value #C\": \"Rate of Received Packets\",\n                                  \"Value #D\": \"Rate of Transmitted Packets\",\n                                  \"Value #E\": \"Rate of Received Packets Dropped\",\n                                  \"Value #F\": \"Rate of Transmitted Packets Dropped\",\n                                  \"pod\": \"Pod\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"binBps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 18\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (pod) (\\n    rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Receive Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"binBps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 18\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (pod) (\\n    rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Transmit Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 27\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (pod) (\\n    rate(container_network_receive_packets_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 27\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (pod) (\\n    rate(container_network_transmit_packets_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 36\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (pod) (\\n    rate(container_network_receive_packets_dropped_total{cluster=\\\"$cluster\\\",namespace!=\\\"\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 36\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum by (pod) (\\n    rate(container_network_transmit_packets_dropped_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n  * on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n)\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets Dropped\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"allValue\": \".+\",\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"kube-system\",\n                          \"value\": \"kube-system\"\n                      },\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": \"namespace\",\n                      \"name\": \"namespace\",\n                      \"query\": \"label_values(container_network_receive_packets_total{cluster=\\\"$cluster\\\"}, namespace)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Networking / Namespace (Pods)\",\n          \"uid\": \"8b7a8b326d7a6f1f04244066368c67af\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-namespace-by-pod\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    namespace-by-workload.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"color\": {\n                              \"fixedColor\": \"green\",\n                              \"mode\": \"fixed\"\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"displayMode\": \"basic\",\n                      \"showUnfilled\": false\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n* on (cluster,namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Current Rate of Bytes Received\",\n                  \"type\": \"bargauge\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"color\": {\n                              \"fixedColor\": \"green\",\n                              \"mode\": \"fixed\"\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"displayMode\": \"basic\",\n                      \"showUnfilled\": false\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n* on (cluster,namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Current Rate of Bytes Transmitted\",\n                  \"type\": \"bargauge\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Bytes/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"binBps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Packets/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"pps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Workload\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"links\",\n                                      \"value\": [\n                                          {\n                                              \"title\": \"Drill down\",\n                                              \"url\": \"/d/728bf77cc1166d2f3133bf25846876cc/kubernetes-networking-workload?${datasource:queryparam}&var-cluster=${cluster}&var-namespace=${namespace}&var-type=${__data.fields.Type}&var-workload=${__data.fields.Workload}\"\n                                          }\n                                      ]\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 3,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod) kube_pod_info{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\",host_network=\\\"false\\\"}\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload, workload_type))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod) kube_pod_info{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\",host_network=\\\"false\\\"}\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload, workload_type))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(avg(rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod) kube_pod_info{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\",host_network=\\\"false\\\"}\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload, workload_type))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(avg(rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod) kube_pod_info{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\",host_network=\\\"false\\\"}\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload, workload_type))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_receive_packets_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod) kube_pod_info{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\",host_network=\\\"false\\\"}\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload, workload_type))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_transmit_packets_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod) kube_pod_info{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\",host_network=\\\"false\\\"}\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload, workload_type))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_receive_packets_dropped_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod) kube_pod_info{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\",host_network=\\\"false\\\"}\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload, workload_type))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_transmit_packets_dropped_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod) kube_pod_info{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\",host_network=\\\"false\\\"}\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload, workload_type))\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Current Status\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"joinByField\",\n                          \"options\": {\n                              \"byField\": \"workload\",\n                              \"mode\": \"outer\"\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n                                  \"Time\": true,\n                                  \"Time 1\": true,\n                                  \"Time 2\": true,\n                                  \"Time 3\": true,\n                                  \"Time 4\": true,\n                                  \"Time 5\": true,\n                                  \"Time 6\": true,\n                                  \"Time 7\": true,\n                                  \"Time 8\": true,\n                                  \"workload_type 2\": true,\n                                  \"workload_type 3\": true,\n                                  \"workload_type 4\": true,\n                                  \"workload_type 5\": true,\n                                  \"workload_type 6\": true,\n                                  \"workload_type 7\": true,\n                                  \"workload_type 8\": true\n                              },\n                              \"indexByName\": {\n                                  \"Time 1\": 0,\n                                  \"Time 2\": 1,\n                                  \"Time 3\": 2,\n                                  \"Time 4\": 3,\n                                  \"Time 5\": 4,\n                                  \"Time 6\": 5,\n                                  \"Time 7\": 6,\n                                  \"Time 8\": 7,\n                                  \"Value #A\": 10,\n                                  \"Value #B\": 11,\n                                  \"Value #C\": 12,\n                                  \"Value #D\": 13,\n                                  \"Value #E\": 14,\n                                  \"Value #F\": 15,\n                                  \"Value #G\": 16,\n                                  \"Value #H\": 17,\n                                  \"workload\": 8,\n                                  \"workload_type 1\": 9,\n                                  \"workload_type 2\": 18,\n                                  \"workload_type 3\": 19,\n                                  \"workload_type 4\": 20,\n                                  \"workload_type 5\": 21,\n                                  \"workload_type 6\": 22,\n                                  \"workload_type 7\": 23,\n                                  \"workload_type 8\": 24\n                              },\n                              \"renameByName\": {\n                                  \"Value #A\": \"Rx Bytes\",\n                                  \"Value #B\": \"Tx Bytes\",\n                                  \"Value #C\": \"Rx Bytes (Avg)\",\n                                  \"Value #D\": \"Tx Bytes (Avg)\",\n                                  \"Value #E\": \"Rx Packets\",\n                                  \"Value #F\": \"Tx Packets\",\n                                  \"Value #G\": \"Rx Packets Dropped\",\n                                  \"Value #H\": \"Tx Packets Dropped\",\n                                  \"workload\": \"Workload\",\n                                  \"workload_type 1\": \"Type\"\n                              }\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 18\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n* on (cluster,namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Receive Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 18\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n* on (cluster,namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Transmit Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 27\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(avg(rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n* on (cluster,namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Average Container Bandwidth by Workload: Received\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 27\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(avg(rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n* on (cluster,namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Average Container Bandwidth by Workload: Transmitted\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 36\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_receive_packets_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n* on (cluster,namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 36\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_transmit_packets_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n* on (cluster,namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 45\n                  },\n                  \"id\": 10,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_receive_packets_dropped_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n* on (cluster,namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 45\n                  },\n                  \"id\": 11,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_transmit_packets_dropped_total{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\"}[$__rate_interval])\\n* on (cluster,namespace,pod) group_left ()\\n    topk by (cluster,namespace,pod) (\\n      1,\\n      max by (cluster,namespace,pod) (kube_pod_info{host_network=\\\"false\\\"})\\n    )\\n* on (cluster,namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=\\\"$namespace\\\", workload=~\\\".+\\\", workload_type=~\\\"$type\\\"}) by (workload))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets Dropped\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"kube-system\",\n                          \"value\": \"kube-system\"\n                      },\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"namespace\",\n                      \"name\": \"namespace\",\n                      \"query\": \"label_values(container_network_receive_packets_total{cluster=\\\"$cluster\\\"}, namespace)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": \"workload_type\",\n                      \"name\": \"type\",\n                      \"query\": \"label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=\\\"$namespace\\\", workload=~\\\".+\\\"}, workload_type)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Networking / Namespace (Workload)\",\n          \"uid\": \"bbb2a765a623ae38130206c7d94a160f\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-namespace-by-workload\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    node-cluster-rsrc-use.json: |-\n      {\n          \"graphTooltip\": 1,\n          \"panels\": [\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"CPU\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 1\n                  },\n                  \"id\": 2,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"((\\n  instance:node_cpu_utilisation:rate5m{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}\\n  *\\n  instance:node_num_cpu:sum{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}\\n) != 0 )\\n/ scalar(sum(instance:node_num_cpu:sum{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}))\\n\",\n                          \"legendFormat\": \"{{ instance }}\"\n                      }\n                  ],\n                  \"title\": \"CPU Utilisation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 1\n                  },\n                  \"id\": 3,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"(\\n  instance:node_load1_per_cpu:ratio{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}\\n  / scalar(count(instance:node_load1_per_cpu:ratio{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}))\\n)  != 0\\n\",\n                          \"legendFormat\": \"{{ instance }}\"\n                      }\n                  ],\n                  \"title\": \"CPU Saturation (Load1 per CPU)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 8\n                  },\n                  \"id\": 4,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Memory\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 5,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"(\\n  instance:node_memory_utilisation:ratio{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}\\n  / scalar(count(instance:node_memory_utilisation:ratio{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}))\\n) != 0\\n\",\n                          \"legendFormat\": \"{{ instance }}\"\n                      }\n                  ],\n                  \"title\": \"Memory Utilisation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"rds\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 9\n                  },\n                  \"id\": 6,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_vmstat_pgmajfault:rate5m{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"{{ instance }}\"\n                      }\n                  ],\n                  \"title\": \"Memory Saturation (Major Page Faults)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 16\n                  },\n                  \"id\": 7,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Network\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"Bps\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Transmit/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.transform\",\n                                      \"value\": \"negative-Y\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 17\n                  },\n                  \"id\": 8,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_network_receive_bytes_excluding_lo:rate5m{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"{{ instance }} Receive\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_network_transmit_bytes_excluding_lo:rate5m{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"{{ instance }} Transmit\"\n                      }\n                  ],\n                  \"title\": \"Network Utilisation (Bytes Receive/Transmit)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"Bps\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Transmit/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.transform\",\n                                      \"value\": \"negative-Y\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 17\n                  },\n                  \"id\": 9,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_network_receive_drop_excluding_lo:rate5m{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"{{ instance }} Receive\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_network_transmit_drop_excluding_lo:rate5m{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"{{ instance }} Transmit\"\n                      }\n                  ],\n                  \"title\": \"Network Saturation (Drops Receive/Transmit)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 24\n                  },\n                  \"id\": 10,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Disk IO\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 25\n                  },\n                  \"id\": 11,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance_device:node_disk_io_time_seconds:rate5m{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}\\n/ scalar(count(instance_device:node_disk_io_time_seconds:rate5m{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}))\\n\",\n                          \"legendFormat\": \"{{ instance }} {{device}}\"\n                      }\n                  ],\n                  \"title\": \"Disk IO Utilisation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 25\n                  },\n                  \"id\": 12,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance_device:node_disk_io_time_weighted_seconds:rate5m{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}\\n/ scalar(count(instance_device:node_disk_io_time_weighted_seconds:rate5m{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}))\\n\",\n                          \"legendFormat\": \"{{ instance }} {{device}}\"\n                      }\n                  ],\n                  \"title\": \"Disk IO Saturation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 34\n                  },\n                  \"id\": 13,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Disk Space\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 35\n                  },\n                  \"id\": 14,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum without (device) (\\n  max without (fstype, mountpoint) ((\\n    node_filesystem_size_bytes{job=\\\"node-exporter\\\", fstype!=\\\"\\\", mountpoint!=\\\"\\\", cluster=\\\"$cluster\\\"}\\n    -\\n    node_filesystem_avail_bytes{job=\\\"node-exporter\\\", fstype!=\\\"\\\", mountpoint!=\\\"\\\", cluster=\\\"$cluster\\\"}\\n  ) != 0)\\n)\\n/ scalar(sum(max without (fstype, mountpoint) (node_filesystem_size_bytes{job=\\\"node-exporter\\\", fstype!=\\\"\\\", mountpoint!=\\\"\\\", cluster=\\\"$cluster\\\"})))\\n\",\n                          \"legendFormat\": \"{{ instance }}\"\n                      }\n                  ],\n                  \"title\": \"Disk Space Utilisation\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"30s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"node-exporter-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 2,\n                      \"includeAll\": false,\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(node_time_seconds, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Node Exporter / USE Method / Cluster\",\n          \"uid\": \"3e97d1d02672cdd0861f4c97c64f89b2\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-node-cluster-rsrc-use\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    node-rsrc-use.json: |-\n      {\n          \"graphTooltip\": 1,\n          \"panels\": [\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"CPU\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 1\n                  },\n                  \"id\": 2,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_cpu_utilisation:rate5m{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"Utilisation\"\n                      }\n                  ],\n                  \"title\": \"CPU Utilisation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 1\n                  },\n                  \"id\": 3,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_load1_per_cpu:ratio{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"Saturation\"\n                      }\n                  ],\n                  \"title\": \"CPU Saturation (Load1 per CPU)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 8\n                  },\n                  \"id\": 4,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Memory\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 5,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_memory_utilisation:ratio{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"Utilisation\"\n                      }\n                  ],\n                  \"title\": \"Memory Utilisation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"rds\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 9\n                  },\n                  \"id\": 6,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_vmstat_pgmajfault:rate5m{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"Major page Faults\"\n                      }\n                  ],\n                  \"title\": \"Memory Saturation (Major Page Faults)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 16\n                  },\n                  \"id\": 7,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Network\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"Bps\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Transmit/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.transform\",\n                                      \"value\": \"negative-Y\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 17\n                  },\n                  \"id\": 8,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_network_receive_bytes_excluding_lo:rate5m{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"Receive\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_network_transmit_bytes_excluding_lo:rate5m{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"Transmit\"\n                      }\n                  ],\n                  \"title\": \"Network Utilisation (Bytes Receive/Transmit)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"Bps\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/Transmit/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.transform\",\n                                      \"value\": \"negative-Y\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 17\n                  },\n                  \"id\": 9,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_network_receive_drop_excluding_lo:rate5m{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"Receive\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance:node_network_transmit_drop_excluding_lo:rate5m{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"Transmit\"\n                      }\n                  ],\n                  \"title\": \"Network Saturation (Drops Receive/Transmit)\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 24\n                  },\n                  \"id\": 10,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Disk IO\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 25\n                  },\n                  \"id\": 11,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance_device:node_disk_io_time_seconds:rate5m{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"{{device}}\"\n                      }\n                  ],\n                  \"title\": \"Disk IO Utilisation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 25\n                  },\n                  \"id\": 12,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"instance_device:node_disk_io_time_weighted_seconds:rate5m{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} != 0\",\n                          \"legendFormat\": \"{{device}}\"\n                      }\n                  ],\n                  \"title\": \"Disk IO Saturation\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 34\n                  },\n                  \"id\": 13,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Disk Space\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 35\n                  },\n                  \"id\": 14,\n                  \"options\": {\n                      \"legend\": {\n                          \"showLegend\": false\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sort_desc(1 -\\n  (\\n    max without (mountpoint, fstype) (node_filesystem_avail_bytes{job=\\\"node-exporter\\\", fstype!=\\\"\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"})\\n    /\\n    max without (mountpoint, fstype) (node_filesystem_size_bytes{job=\\\"node-exporter\\\", fstype!=\\\"\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"})\\n  ) != 0\\n)\\n\",\n                          \"legendFormat\": \"{{device}}\"\n                      }\n                  ],\n                  \"title\": \"Disk Space Utilisation\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"30s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"node-exporter-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 2,\n                      \"includeAll\": false,\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(node_time_seconds, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"name\": \"instance\",\n                      \"query\": \"label_values(node_exporter_build_info{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\"}, instance)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Node Exporter / USE Method / Node\",\n          \"uid\": \"fac67cfbe174d3ef53eb473d73d9212f\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-node-rsrc-use\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    nodes-aix.json: |-\n      {\n          \"graphTooltip\": 1,\n          \"panels\": [\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"CPU\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"max\": 1,\n                          \"min\": 0,\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 1\n                  },\n                  \"id\": 2,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"(\\n  (1 - sum without (mode) (rate(node_cpu_seconds_total{job=\\\"node-exporter\\\", mode=~\\\"idle|iowait|steal\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}[$__rate_interval])))\\n/ ignoring(cpu) group_left\\n  count without (cpu, mode) (node_cpu_seconds_total{job=\\\"node-exporter\\\", mode=\\\"idle\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"})\\n)\\n\",\n                          \"intervalFactor\": 5,\n                          \"legendFormat\": \"{{cpu}}\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          },\n                          \"min\": 0,\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 1\n                  },\n                  \"id\": 3,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_load1{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"1m load average\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_load5{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"5m load average\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_load15{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"15m load average\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"count(node_cpu_seconds_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", mode=\\\"idle\\\"})\",\n                          \"legendFormat\": \"logical cores\"\n                      }\n                  ],\n                  \"title\": \"Load Average\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 8\n                  },\n                  \"id\": 4,\n                  \"title\": \"Memory\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"none\"\n                              }\n                          },\n                          \"min\": 0,\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 18,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 5,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_memory_total_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"Physical Memory\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"(\\n    node_memory_total_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} -\\n    node_memory_available_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\\n)\\n\",\n                          \"legendFormat\": \"Memory Used\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"max\": 100,\n                          \"min\": 0,\n                          \"thresholds\": {\n                              \"steps\": [\n                                  {\n                                      \"color\": \"rgba(50, 172, 45, 0.97)\"\n                                  },\n                                  {\n                                      \"color\": \"rgba(237, 129, 40, 0.89)\",\n                                      \"value\": 80\n                                  },\n                                  {\n                                      \"color\": \"rgba(245, 54, 54, 0.9)\",\n                                      \"value\": 90\n                                  }\n                              ]\n                          },\n                          \"unit\": \"percent\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 18,\n                      \"y\": 9\n                  },\n                  \"id\": 6,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"100 -\\n(\\n  avg(node_memory_available_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}) /\\n  avg(node_memory_total_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"})\\n  * 100\\n)\\n\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage\",\n                  \"type\": \"gauge\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 18\n                  },\n                  \"id\": 7,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Disk\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          },\n                          \"min\": 0\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/ read| written/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"Bps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/ io time/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 19\n                  },\n                  \"id\": 8,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_disk_read_bytes_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\"}[$__rate_interval])\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}} read\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_disk_written_bytes_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\"}[$__rate_interval])\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}} written\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_disk_io_time_seconds_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\"}[$__rate_interval])\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}} io time\"\n                      }\n                  ],\n                  \"title\": \"Disk I/O\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"thresholds\": {\n                              \"steps\": [\n                                  {\n                                      \"color\": \"green\"\n                                  },\n                                  {\n                                      \"color\": \"yellow\",\n                                      \"value\": 0.8\n                                  },\n                                  {\n                                      \"color\": \"red\",\n                                      \"value\": 0.9\n                                  }\n                              ]\n                          },\n                          \"unit\": \"decbytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Mounted on\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.width\",\n                                      \"value\": 260\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Size\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.width\",\n                                      \"value\": 93\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Used\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.width\",\n                                      \"value\": 72\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Available\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.width\",\n                                      \"value\": 88\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Used, %\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  },\n                                  {\n                                      \"id\": \"custom.cellOptions\",\n                                      \"value\": {\n                                          \"type\": \"gauge\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"max\",\n                                      \"value\": 1\n                                  },\n                                  {\n                                      \"id\": \"min\",\n                                      \"value\": 0\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 19\n                  },\n                  \"id\": 9,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"max by (mountpoint) (node_filesystem_size_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", fstype!=\\\"\\\", mountpoint!=\\\"\\\"})\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true,\n                          \"legendFormat\": \"\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"max by (mountpoint) (node_filesystem_avail_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", fstype!=\\\"\\\", mountpoint!=\\\"\\\"})\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true,\n                          \"legendFormat\": \"\"\n                      }\n                  ],\n                  \"title\": \"Disk Space Usage\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"groupBy\",\n                          \"options\": {\n                              \"fields\": {\n                                  \"Value #A\": {\n                                      \"aggregations\": [\n                                          \"lastNotNull\"\n                                      ],\n                                      \"operation\": \"aggregate\"\n                                  },\n                                  \"Value #B\": {\n                                      \"aggregations\": [\n                                          \"lastNotNull\"\n                                      ],\n                                      \"operation\": \"aggregate\"\n                                  },\n                                  \"mountpoint\": {\n                                      \"aggregations\": [\n\n                                      ],\n                                      \"operation\": \"groupby\"\n                                  }\n                              }\n                          }\n                      },\n                      {\n                          \"id\": \"merge\"\n                      },\n                      {\n                          \"id\": \"calculateField\",\n                          \"options\": {\n                              \"alias\": \"Used\",\n                              \"binary\": {\n                                  \"left\": \"Value #A (lastNotNull)\",\n                                  \"operator\": \"-\",\n                                  \"reducer\": \"sum\",\n                                  \"right\": \"Value #B (lastNotNull)\"\n                              },\n                              \"mode\": \"binary\",\n                              \"reduce\": {\n                                  \"reducer\": \"sum\"\n                              }\n                          }\n                      },\n                      {\n                          \"id\": \"calculateField\",\n                          \"options\": {\n                              \"alias\": \"Used, %\",\n                              \"binary\": {\n                                  \"left\": \"Used\",\n                                  \"operator\": \"/\",\n                                  \"reducer\": \"sum\",\n                                  \"right\": \"Value #A (lastNotNull)\"\n                              },\n                              \"mode\": \"binary\",\n                              \"reduce\": {\n                                  \"reducer\": \"sum\"\n                              }\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n\n                              },\n                              \"indexByName\": {\n\n                              },\n                              \"renameByName\": {\n                                  \"Value #A (lastNotNull)\": \"Size\",\n                                  \"Value #B (lastNotNull)\": \"Available\",\n                                  \"mountpoint\": \"Mounted on\"\n                              }\n                          }\n                      },\n                      {\n                          \"id\": \"sortBy\",\n                          \"options\": {\n                              \"fields\": {\n\n                              },\n                              \"sort\": [\n                                  {\n                                      \"field\": \"Mounted on\"\n                                  }\n                              ]\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 26\n                  },\n                  \"id\": 10,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Network\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"description\": \"Network received (bits/s)\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          },\n                          \"min\": 0,\n                          \"unit\": \"bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 27\n                  },\n                  \"id\": 11,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_network_receive_bytes_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device!=\\\"lo\\\"}[$__rate_interval]) * 8\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}}\"\n                      }\n                  ],\n                  \"title\": \"Network Received\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"description\": \"Network transmitted (bits/s)\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0\n                          },\n                          \"min\": 0,\n                          \"unit\": \"bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 27\n                  },\n                  \"id\": 12,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_network_transmit_bytes_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device!=\\\"lo\\\"}[$__rate_interval]) * 8\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}}\"\n                      }\n                  ],\n                  \"title\": \"Network Transmitted\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"30s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"node-exporter-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 2,\n                      \"label\": \"Cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(node_uname_info{job=\\\"node-exporter\\\", sysname!=\\\"Darwin\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"label\": \"Instance\",\n                      \"name\": \"instance\",\n                      \"query\": \"label_values(node_uname_info{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\", sysname!=\\\"Darwin\\\"}, instance)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Node Exporter / AIX\",\n          \"uid\": \"7e0a61e486f727d763fb1d86fdd629c2\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-nodes-aix\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    nodes-darwin.json: |-\n      {\n          \"graphTooltip\": 1,\n          \"panels\": [\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"CPU\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"max\": 1,\n                          \"min\": 0,\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 1\n                  },\n                  \"id\": 2,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"(\\n  (1 - sum without (mode) (rate(node_cpu_seconds_total{job=\\\"node-exporter\\\", mode=~\\\"idle|iowait|steal\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}[$__rate_interval])))\\n/ ignoring(cpu) group_left\\n  count without (cpu, mode) (node_cpu_seconds_total{job=\\\"node-exporter\\\", mode=\\\"idle\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"})\\n)\\n\",\n                          \"intervalFactor\": 5,\n                          \"legendFormat\": \"{{cpu}}\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          },\n                          \"min\": 0,\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 1\n                  },\n                  \"id\": 3,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_load1{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"1m load average\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_load5{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"5m load average\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_load15{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"15m load average\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"count(node_cpu_seconds_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", mode=\\\"idle\\\"})\",\n                          \"legendFormat\": \"logical cores\"\n                      }\n                  ],\n                  \"title\": \"Load Average\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 8\n                  },\n                  \"id\": 4,\n                  \"title\": \"Memory\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"none\"\n                              }\n                          },\n                          \"min\": 0,\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 18,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 5,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_memory_total_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"Physical Memory\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"(\\n    node_memory_internal_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} -\\n    node_memory_purgeable_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} +\\n    node_memory_wired_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} +\\n    node_memory_compressed_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\\n)\\n\",\n                          \"legendFormat\": \"Memory Used\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"(\\n    node_memory_internal_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"} -\\n    node_memory_purgeable_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\\n)\\n\",\n                          \"legendFormat\": \"App Memory\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_memory_wired_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"Wired Memory\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_memory_compressed_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"Compressed\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"max\": 100,\n                          \"min\": 0,\n                          \"thresholds\": {\n                              \"steps\": [\n                                  {\n                                      \"color\": \"rgba(50, 172, 45, 0.97)\"\n                                  },\n                                  {\n                                      \"color\": \"rgba(237, 129, 40, 0.89)\",\n                                      \"value\": 80\n                                  },\n                                  {\n                                      \"color\": \"rgba(245, 54, 54, 0.9)\",\n                                      \"value\": 90\n                                  }\n                              ]\n                          },\n                          \"unit\": \"percent\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 18,\n                      \"y\": 9\n                  },\n                  \"id\": 6,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"(\\n    (\\n      avg(node_memory_internal_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}) -\\n      avg(node_memory_purgeable_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}) +\\n      avg(node_memory_wired_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}) +\\n      avg(node_memory_compressed_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"})\\n    ) /\\n    avg(node_memory_total_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"})\\n)\\n*\\n100\\n\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage\",\n                  \"type\": \"gauge\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 18\n                  },\n                  \"id\": 7,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Disk\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          },\n                          \"min\": 0\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/ read| written/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"Bps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/ io time/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 19\n                  },\n                  \"id\": 8,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_disk_read_bytes_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\"}[$__rate_interval])\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}} read\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_disk_written_bytes_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\"}[$__rate_interval])\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}} written\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_disk_io_time_seconds_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\"}[$__rate_interval])\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}} io time\"\n                      }\n                  ],\n                  \"title\": \"Disk I/O\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"thresholds\": {\n                              \"steps\": [\n                                  {\n                                      \"color\": \"green\"\n                                  },\n                                  {\n                                      \"color\": \"yellow\",\n                                      \"value\": 0.8\n                                  },\n                                  {\n                                      \"color\": \"red\",\n                                      \"value\": 0.9\n                                  }\n                              ]\n                          },\n                          \"unit\": \"decbytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Mounted on\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.width\",\n                                      \"value\": 260\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Size\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.width\",\n                                      \"value\": 93\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Used\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.width\",\n                                      \"value\": 72\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Available\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.width\",\n                                      \"value\": 88\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Used, %\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  },\n                                  {\n                                      \"id\": \"custom.cellOptions\",\n                                      \"value\": {\n                                          \"type\": \"gauge\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"max\",\n                                      \"value\": 1\n                                  },\n                                  {\n                                      \"id\": \"min\",\n                                      \"value\": 0\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 19\n                  },\n                  \"id\": 9,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"max by (mountpoint) (node_filesystem_size_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", fstype!=\\\"\\\", mountpoint!=\\\"\\\"})\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true,\n                          \"legendFormat\": \"\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"max by (mountpoint) (node_filesystem_avail_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", fstype!=\\\"\\\", mountpoint!=\\\"\\\"})\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true,\n                          \"legendFormat\": \"\"\n                      }\n                  ],\n                  \"title\": \"Disk Space Usage\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"groupBy\",\n                          \"options\": {\n                              \"fields\": {\n                                  \"Value #A\": {\n                                      \"aggregations\": [\n                                          \"lastNotNull\"\n                                      ],\n                                      \"operation\": \"aggregate\"\n                                  },\n                                  \"Value #B\": {\n                                      \"aggregations\": [\n                                          \"lastNotNull\"\n                                      ],\n                                      \"operation\": \"aggregate\"\n                                  },\n                                  \"mountpoint\": {\n                                      \"aggregations\": [\n\n                                      ],\n                                      \"operation\": \"groupby\"\n                                  }\n                              }\n                          }\n                      },\n                      {\n                          \"id\": \"merge\"\n                      },\n                      {\n                          \"id\": \"calculateField\",\n                          \"options\": {\n                              \"alias\": \"Used\",\n                              \"binary\": {\n                                  \"left\": \"Value #A (lastNotNull)\",\n                                  \"operator\": \"-\",\n                                  \"reducer\": \"sum\",\n                                  \"right\": \"Value #B (lastNotNull)\"\n                              },\n                              \"mode\": \"binary\",\n                              \"reduce\": {\n                                  \"reducer\": \"sum\"\n                              }\n                          }\n                      },\n                      {\n                          \"id\": \"calculateField\",\n                          \"options\": {\n                              \"alias\": \"Used, %\",\n                              \"binary\": {\n                                  \"left\": \"Used\",\n                                  \"operator\": \"/\",\n                                  \"reducer\": \"sum\",\n                                  \"right\": \"Value #A (lastNotNull)\"\n                              },\n                              \"mode\": \"binary\",\n                              \"reduce\": {\n                                  \"reducer\": \"sum\"\n                              }\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n\n                              },\n                              \"indexByName\": {\n\n                              },\n                              \"renameByName\": {\n                                  \"Value #A (lastNotNull)\": \"Size\",\n                                  \"Value #B (lastNotNull)\": \"Available\",\n                                  \"mountpoint\": \"Mounted on\"\n                              }\n                          }\n                      },\n                      {\n                          \"id\": \"sortBy\",\n                          \"options\": {\n                              \"fields\": {\n\n                              },\n                              \"sort\": [\n                                  {\n                                      \"field\": \"Mounted on\"\n                                  }\n                              ]\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 26\n                  },\n                  \"id\": 10,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Network\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"description\": \"Network received (bits/s)\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          },\n                          \"min\": 0,\n                          \"unit\": \"bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 27\n                  },\n                  \"id\": 11,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_network_receive_bytes_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device!=\\\"lo\\\"}[$__rate_interval]) * 8\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}}\"\n                      }\n                  ],\n                  \"title\": \"Network Received\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"description\": \"Network transmitted (bits/s)\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0\n                          },\n                          \"min\": 0,\n                          \"unit\": \"bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 27\n                  },\n                  \"id\": 12,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_network_transmit_bytes_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device!=\\\"lo\\\"}[$__rate_interval]) * 8\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}}\"\n                      }\n                  ],\n                  \"title\": \"Network Transmitted\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"30s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"node-exporter-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 2,\n                      \"label\": \"Cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(node_uname_info{job=\\\"node-exporter\\\", sysname=\\\"Darwin\\\"},  cluster)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"label\": \"Instance\",\n                      \"name\": \"instance\",\n                      \"query\": \"label_values(node_uname_info{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\", sysname=\\\"Darwin\\\"}, instance)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Node Exporter / MacOS\",\n          \"uid\": \"629701ea43bf69291922ea45f4a87d37\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-nodes-darwin\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    nodes.json: |-\n      {\n          \"graphTooltip\": 1,\n          \"panels\": [\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"CPU\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"max\": 1,\n                          \"min\": 0,\n                          \"unit\": \"percentunit\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 1\n                  },\n                  \"id\": 2,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"(\\n  (1 - sum without (mode) (rate(node_cpu_seconds_total{job=\\\"node-exporter\\\", mode=~\\\"idle|iowait|steal\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}[$__rate_interval])))\\n/ ignoring(cpu) group_left\\n  count without (cpu, mode) (node_cpu_seconds_total{job=\\\"node-exporter\\\", mode=\\\"idle\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"})\\n)\\n\",\n                          \"intervalFactor\": 5,\n                          \"legendFormat\": \"{{cpu}}\"\n                      }\n                  ],\n                  \"title\": \"CPU Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          },\n                          \"min\": 0,\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 1\n                  },\n                  \"id\": 3,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_load1{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"1m load average\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_load5{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"5m load average\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_load15{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"15m load average\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"count(node_cpu_seconds_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", mode=\\\"idle\\\"})\",\n                          \"legendFormat\": \"logical cores\"\n                      }\n                  ],\n                  \"title\": \"Load Average\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 8\n                  },\n                  \"id\": 4,\n                  \"title\": \"Memory\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"min\": 0,\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 18,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 5,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"(\\n  node_memory_MemTotal_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\\n-\\n  node_memory_MemFree_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\\n-\\n  node_memory_Buffers_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\\n-\\n  node_memory_Cached_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\\n)\\n\",\n                          \"legendFormat\": \"memory used\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_memory_Buffers_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"memory buffers\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_memory_Cached_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"memory cached\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"node_memory_MemFree_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}\",\n                          \"legendFormat\": \"memory free\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"max\": 100,\n                          \"min\": 0,\n                          \"thresholds\": {\n                              \"steps\": [\n                                  {\n                                      \"color\": \"rgba(50, 172, 45, 0.97)\"\n                                  },\n                                  {\n                                      \"color\": \"rgba(237, 129, 40, 0.89)\",\n                                      \"value\": 80\n                                  },\n                                  {\n                                      \"color\": \"rgba(245, 54, 54, 0.9)\",\n                                      \"value\": 90\n                                  }\n                              ]\n                          },\n                          \"unit\": \"percent\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 18,\n                      \"y\": 9\n                  },\n                  \"id\": 6,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"100 -\\n(\\n  avg(node_memory_MemAvailable_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"}) /\\n  avg(node_memory_MemTotal_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\"})\\n* 100\\n)\\n\"\n                      }\n                  ],\n                  \"title\": \"Memory Usage\",\n                  \"type\": \"gauge\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 18\n                  },\n                  \"id\": 7,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Disk\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          },\n                          \"min\": 0\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/ read| written/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"Bps\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byRegexp\",\n                                  \"options\": \"/ io time/\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 19\n                  },\n                  \"id\": 8,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_disk_read_bytes_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\"}[$__rate_interval])\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}} read\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_disk_written_bytes_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\"}[$__rate_interval])\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}} written\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_disk_io_time_seconds_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device=~\\\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\\\"}[$__rate_interval])\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}} io time\"\n                      }\n                  ],\n                  \"title\": \"Disk I/O\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"thresholds\": {\n                              \"steps\": [\n                                  {\n                                      \"color\": \"green\"\n                                  },\n                                  {\n                                      \"color\": \"yellow\",\n                                      \"value\": 0.8\n                                  },\n                                  {\n                                      \"color\": \"red\",\n                                      \"value\": 0.9\n                                  }\n                              ]\n                          },\n                          \"unit\": \"decbytes\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Mounted on\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.width\",\n                                      \"value\": 260\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Size\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.width\",\n                                      \"value\": 93\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Used\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.width\",\n                                      \"value\": 72\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Available\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.width\",\n                                      \"value\": 88\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Used, %\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"percentunit\"\n                                  },\n                                  {\n                                      \"id\": \"custom.cellOptions\",\n                                      \"value\": {\n                                          \"type\": \"gauge\"\n                                      }\n                                  },\n                                  {\n                                      \"id\": \"max\",\n                                      \"value\": 1\n                                  },\n                                  {\n                                      \"id\": \"min\",\n                                      \"value\": 0\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 19\n                  },\n                  \"id\": 9,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"max by (mountpoint) (node_filesystem_size_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", fstype!=\\\"\\\", mountpoint!=\\\"\\\"})\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true,\n                          \"legendFormat\": \"\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"max by (mountpoint) (node_filesystem_avail_bytes{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", fstype!=\\\"\\\", mountpoint!=\\\"\\\"})\\n\",\n                          \"format\": \"table\",\n                          \"instant\": true,\n                          \"legendFormat\": \"\"\n                      }\n                  ],\n                  \"title\": \"Disk Space Usage\",\n                  \"transformations\": [\n                      {\n                          \"id\": \"groupBy\",\n                          \"options\": {\n                              \"fields\": {\n                                  \"Value #A\": {\n                                      \"aggregations\": [\n                                          \"lastNotNull\"\n                                      ],\n                                      \"operation\": \"aggregate\"\n                                  },\n                                  \"Value #B\": {\n                                      \"aggregations\": [\n                                          \"lastNotNull\"\n                                      ],\n                                      \"operation\": \"aggregate\"\n                                  },\n                                  \"mountpoint\": {\n                                      \"aggregations\": [\n\n                                      ],\n                                      \"operation\": \"groupby\"\n                                  }\n                              }\n                          }\n                      },\n                      {\n                          \"id\": \"merge\"\n                      },\n                      {\n                          \"id\": \"calculateField\",\n                          \"options\": {\n                              \"alias\": \"Used\",\n                              \"binary\": {\n                                  \"left\": \"Value #A (lastNotNull)\",\n                                  \"operator\": \"-\",\n                                  \"reducer\": \"sum\",\n                                  \"right\": \"Value #B (lastNotNull)\"\n                              },\n                              \"mode\": \"binary\",\n                              \"reduce\": {\n                                  \"reducer\": \"sum\"\n                              }\n                          }\n                      },\n                      {\n                          \"id\": \"calculateField\",\n                          \"options\": {\n                              \"alias\": \"Used, %\",\n                              \"binary\": {\n                                  \"left\": \"Used\",\n                                  \"operator\": \"/\",\n                                  \"reducer\": \"sum\",\n                                  \"right\": \"Value #A (lastNotNull)\"\n                              },\n                              \"mode\": \"binary\",\n                              \"reduce\": {\n                                  \"reducer\": \"sum\"\n                              }\n                          }\n                      },\n                      {\n                          \"id\": \"organize\",\n                          \"options\": {\n                              \"excludeByName\": {\n\n                              },\n                              \"indexByName\": {\n\n                              },\n                              \"renameByName\": {\n                                  \"Value #A (lastNotNull)\": \"Size\",\n                                  \"Value #B (lastNotNull)\": \"Available\",\n                                  \"mountpoint\": \"Mounted on\"\n                              }\n                          }\n                      },\n                      {\n                          \"id\": \"sortBy\",\n                          \"options\": {\n                              \"fields\": {\n\n                              },\n                              \"sort\": [\n                                  {\n                                      \"field\": \"Mounted on\"\n                                  }\n                              ]\n                          }\n                      }\n                  ],\n                  \"type\": \"table\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 26\n                  },\n                  \"id\": 10,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Network\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"description\": \"Network received (bits/s)\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          },\n                          \"min\": 0,\n                          \"unit\": \"bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 27\n                  },\n                  \"id\": 11,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_network_receive_bytes_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device!=\\\"lo\\\"}[$__rate_interval]) * 8\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}}\"\n                      }\n                  ],\n                  \"title\": \"Network Received\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"${datasource}\"\n                  },\n                  \"description\": \"Network transmitted (bits/s)\",\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0\n                          },\n                          \"min\": 0,\n                          \"unit\": \"bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 27\n                  },\n                  \"id\": 12,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(node_network_transmit_bytes_total{job=\\\"node-exporter\\\", instance=\\\"$instance\\\", cluster=\\\"$cluster\\\", device!=\\\"lo\\\"}[$__rate_interval]) * 8\",\n                          \"intervalFactor\": 1,\n                          \"legendFormat\": \"{{device}}\"\n                      }\n                  ],\n                  \"title\": \"Network Transmitted\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"30s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"node-exporter-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 2,\n                      \"label\": \"Cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(node_uname_info{job=\\\"node-exporter\\\", sysname!=\\\"Darwin\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"label\": \"Instance\",\n                      \"name\": \"instance\",\n                      \"query\": \"label_values(node_uname_info{job=\\\"node-exporter\\\", cluster=\\\"$cluster\\\", sysname!=\\\"Darwin\\\"}, instance)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Node Exporter / Nodes\",\n          \"uid\": \"7d57716318ee0dddbac5a7f451fb7753\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-nodes\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    persistentvolumesusage.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 18,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(\\n  sum without(instance, node) (topk(1, (kubelet_volume_stats_capacity_bytes{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", namespace=\\\"$namespace\\\", persistentvolumeclaim=\\\"$volume\\\"})))\\n  -\\n  sum without(instance, node) (topk(1, (kubelet_volume_stats_available_bytes{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", namespace=\\\"$namespace\\\", persistentvolumeclaim=\\\"$volume\\\"})))\\n)\\n\",\n                          \"legendFormat\": \"Used Space\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum without(instance, node) (topk(1, (kubelet_volume_stats_available_bytes{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", namespace=\\\"$namespace\\\", persistentvolumeclaim=\\\"$volume\\\"})))\\n\",\n                          \"legendFormat\": \"Free Space\"\n                      }\n                  ],\n                  \"title\": \"Volume Space Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"color\": {\n                              \"mode\": \"thresholds\"\n                          },\n                          \"max\": 100,\n                          \"min\": 0,\n                          \"thresholds\": {\n                              \"mode\": \"absolute\",\n                              \"steps\": [\n                                  {\n                                      \"color\": \"green\",\n                                      \"value\": 0\n                                  },\n                                  {\n                                      \"color\": \"orange\",\n                                      \"value\": 80\n                                  },\n                                  {\n                                      \"color\": \"red\",\n                                      \"value\": 90\n                                  }\n                              ]\n                          },\n                          \"unit\": \"percent\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 18,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"max without(instance,node) (\\n(\\n  topk(1, kubelet_volume_stats_capacity_bytes{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", namespace=\\\"$namespace\\\", persistentvolumeclaim=\\\"$volume\\\"})\\n  -\\n  topk(1, kubelet_volume_stats_available_bytes{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", namespace=\\\"$namespace\\\", persistentvolumeclaim=\\\"$volume\\\"})\\n)\\n/\\ntopk(1, kubelet_volume_stats_capacity_bytes{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", namespace=\\\"$namespace\\\", persistentvolumeclaim=\\\"$volume\\\"})\\n* 100)\\n\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Volume Space Usage\",\n                  \"type\": \"gauge\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 18,\n                      \"y\": 7\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum without(instance, node) (topk(1, (kubelet_volume_stats_inodes_used{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", namespace=\\\"$namespace\\\", persistentvolumeclaim=\\\"$volume\\\"})))\",\n                          \"legendFormat\": \"Used inodes\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"(\\n  sum without(instance, node) (topk(1, (kubelet_volume_stats_inodes{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", namespace=\\\"$namespace\\\", persistentvolumeclaim=\\\"$volume\\\"})))\\n  -\\n  sum without(instance, node) (topk(1, (kubelet_volume_stats_inodes_used{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", namespace=\\\"$namespace\\\", persistentvolumeclaim=\\\"$volume\\\"})))\\n)\\n\",\n                          \"legendFormat\": \"Free inodes\"\n                      }\n                  ],\n                  \"title\": \"Volume inodes Usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"color\": {\n                              \"mode\": \"thresholds\"\n                          },\n                          \"max\": 100,\n                          \"min\": 0,\n                          \"thresholds\": {\n                              \"mode\": \"absolute\",\n                              \"steps\": [\n                                  {\n                                      \"color\": \"green\",\n                                      \"value\": 0\n                                  },\n                                  {\n                                      \"color\": \"orange\",\n                                      \"value\": 80\n                                  },\n                                  {\n                                      \"color\": \"red\",\n                                      \"value\": 90\n                                  }\n                              ]\n                          },\n                          \"unit\": \"percent\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 18,\n                      \"y\": 7\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"max without(instance,node) (\\ntopk(1, kubelet_volume_stats_inodes_used{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", namespace=\\\"$namespace\\\", persistentvolumeclaim=\\\"$volume\\\"})\\n/\\ntopk(1, kubelet_volume_stats_inodes{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", namespace=\\\"$namespace\\\", persistentvolumeclaim=\\\"$volume\\\"})\\n* 100)\\n\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Volume inodes Usage\",\n                  \"type\": \"gauge\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(kubelet_volume_stats_capacity_bytes{job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Namespace\",\n                      \"name\": \"namespace\",\n                      \"query\": \"label_values(kubelet_volume_stats_capacity_bytes{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\"}, namespace)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"PersistentVolumeClaim\",\n                      \"name\": \"volume\",\n                      \"query\": \"label_values(kubelet_volume_stats_capacity_bytes{cluster=\\\"$cluster\\\", job=\\\"kubelet\\\", metrics_path=\\\"/metrics\\\", namespace=\\\"$namespace\\\"}, persistentvolumeclaim)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Persistent Volumes\",\n          \"uid\": \"919b92a8e8041bd567af9edab12c840c\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-persistentvolumesusage\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    pod-total.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"displayName\": \"$pod\",\n                          \"max\": 10000000000,\n                          \"min\": 0,\n                          \"thresholds\": {\n                              \"steps\": [\n                                  {\n                                      \"color\": \"dark-green\",\n                                      \"index\": 0,\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"color\": \"dark-yellow\",\n                                      \"index\": 1,\n                                      \"value\": 5000000000\n                                  },\n                                  {\n                                      \"color\": \"dark-red\",\n                                      \"index\": 2,\n                                      \"value\": 7000000000\n                                  }\n                              ]\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Current Rate of Bytes Received\",\n                  \"type\": \"gauge\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"displayName\": \"$pod\",\n                          \"max\": 10000000000,\n                          \"min\": 0,\n                          \"thresholds\": {\n                              \"steps\": [\n                                  {\n                                      \"color\": \"dark-green\",\n                                      \"index\": 0,\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"color\": \"dark-yellow\",\n                                      \"index\": 1,\n                                      \"value\": 5000000000\n                                  },\n                                  {\n                                      \"color\": \"dark-red\",\n                                      \"index\": 2,\n                                      \"value\": 7000000000\n                                  }\n                              ]\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Current Rate of Bytes Transmitted\",\n                  \"type\": \"gauge\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"binBps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_bytes_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Receive Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"binBps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 9\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_bytes_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Transmit Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 18\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_packets_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 18\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_packets_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 27\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_receive_packets_dropped_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 27\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(container_network_transmit_packets_dropped_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", pod=~\\\"$pod\\\"}[$__rate_interval])) by (pod)\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets Dropped\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"allValue\": \".+\",\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"kube-system\",\n                          \"value\": \"kube-system\"\n                      },\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": \"namespace\",\n                      \"name\": \"namespace\",\n                      \"query\": \"label_values(container_network_receive_packets_total{cluster=\\\"$cluster\\\"}, namespace)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"kube-system\",\n                          \"value\": \"kube-system\"\n                      },\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"pod\",\n                      \"name\": \"pod\",\n                      \"query\": \"label_values(container_network_receive_packets_total{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}, pod)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Networking / Pod\",\n          \"uid\": \"7a18067ce943a40ae25454675c19ff5c\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-pod-total\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    prometheus-remote-write.json: |-\n      {\n          \"panels\": [\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Timestamps\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 1\n                  },\n                  \"id\": 2,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"(\\n  prometheus_remote_storage_highest_timestamp_in_seconds{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\"}\\n-\\n  ignoring(remote_name, url) group_right(instance) (prometheus_remote_storage_queue_highest_sent_timestamp_seconds{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"} != 0)\\n)\\n\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}::{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Highest Timestamp In vs. Highest Timestamp Sent\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 1\n                  },\n                  \"id\": 3,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"clamp_min(\\n  rate(prometheus_remote_storage_highest_timestamp_in_seconds{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\"}[5m])\\n-\\n  ignoring (remote_name, url) group_right(instance) rate(prometheus_remote_storage_queue_highest_sent_timestamp_seconds{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}[5m])\\n, 0)\\n\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Rate[5m]\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 8\n                  },\n                  \"id\": 4,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Samples\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 5,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(\\n  prometheus_remote_storage_samples_in_total{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\"}[5m])\\n-\\n  ignoring(remote_name, url) group_right(instance) (rate(prometheus_remote_storage_succeeded_samples_total{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}[5m]) or rate(prometheus_remote_storage_samples_total{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}[5m]))\\n-\\n  (rate(prometheus_remote_storage_dropped_samples_total{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}[5m]) or rate(prometheus_remote_storage_samples_dropped_total{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}[5m]))\\n\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Rate, in vs. succeeded or dropped [5m]\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 16\n                  },\n                  \"id\": 6,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Shards\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 16\n                  },\n                  \"id\": 7,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"prometheus_remote_storage_shards{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Current Shards\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 0,\n                      \"y\": 23\n                  },\n                  \"id\": 8,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"prometheus_remote_storage_shards_max{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Max Shards\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 8,\n                      \"y\": 23\n                  },\n                  \"id\": 9,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"prometheus_remote_storage_shards_min{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Min Shards\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 16,\n                      \"y\": 23\n                  },\n                  \"id\": 10,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"prometheus_remote_storage_shards_desired{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Desired Shards\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 24\n                  },\n                  \"id\": 11,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Shard Details\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 25\n                  },\n                  \"id\": 12,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"prometheus_remote_storage_shard_capacity{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Shard Capacity\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 25\n                  },\n                  \"id\": 13,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"prometheus_remote_storage_pending_samples{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"} or prometheus_remote_storage_samples_pending{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Pending Samples\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 32\n                  },\n                  \"id\": 14,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Segments\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 33\n                  },\n                  \"id\": 15,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"prometheus_tsdb_wal_segment_current{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\"}\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"TSDB Current Segment\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          },\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 33\n                  },\n                  \"id\": 16,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"prometheus_wal_watcher_current_segment{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\"}\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}} {{consumer}}\"\n                      }\n                  ],\n                  \"title\": \"Remote Write Current Segment\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 40\n                  },\n                  \"id\": 17,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Misc. Rates\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          }\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 0,\n                      \"y\": 41\n                  },\n                  \"id\": 18,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(prometheus_remote_storage_dropped_samples_total{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}[5m]) or rate(prometheus_remote_storage_samples_dropped_total{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}[5m])\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Dropped Samples\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          }\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 6,\n                      \"y\": 41\n                  },\n                  \"id\": 19,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(prometheus_remote_storage_failed_samples_total{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}[5m]) or rate(prometheus_remote_storage_samples_failed_total{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}[5m])\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Failed Samples\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          }\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 12,\n                      \"y\": 41\n                  },\n                  \"id\": 20,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(prometheus_remote_storage_retried_samples_total{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}[5m]) or rate(prometheus_remote_storage_samples_retried_total{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}[5m])\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Retried Samples\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 0,\n                              \"showPoints\": \"never\"\n                          }\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 6,\n                      \"x\": 18,\n                      \"y\": 41\n                  },\n                  \"id\": 21,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(prometheus_remote_storage_enqueue_retries_total{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\", url=~\\\"$url\\\"}[5m])\",\n                          \"format\": \"time_series\",\n                          \"intervalFactor\": 2,\n                          \"legendFormat\": \"{{cluster}}:{{instance}} {{remote_name}}:{{url}}\"\n                      }\n                  ],\n                  \"title\": \"Enqueue Retries\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"prometheus-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"$__all\",\n                          \"value\": \"$__all\"\n                      },\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(prometheus_build_info, cluster)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"includeAll\": true,\n                      \"name\": \"instance\",\n                      \"query\": \"label_values(prometheus_build_info{cluster=~\\\"$cluster\\\"}, instance)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"includeAll\": true,\n                      \"name\": \"url\",\n                      \"query\": \"label_values(prometheus_remote_storage_shards{cluster=~\\\"$cluster\\\", instance=~\\\"$instance\\\"}, url)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timepicker\": {\n              \"refresh_intervals\": [\n                  \"60s\"\n              ]\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Prometheus / Remote Write\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-prometheus-remote-write\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    prometheus.json: |-\n      {\n          \"panels\": [\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Prometheus Stats\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"decimals\": 2,\n                          \"displayName\": \"\",\n                          \"unit\": \"short\"\n                      },\n                      \"overrides\": [\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Time\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"displayName\",\n                                      \"value\": \"Time\"\n                                  },\n                                  {\n                                      \"id\": \"custom.align\",\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"id\": \"custom.hidden\",\n                                      \"value\": \"true\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"cluster\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.align\",\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"short\"\n                                  },\n                                  {\n                                      \"id\": \"decimals\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"displayName\",\n                                      \"value\": \"Cluster\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"job\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"custom.align\",\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"short\"\n                                  },\n                                  {\n                                      \"id\": \"decimals\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"displayName\",\n                                      \"value\": \"Job\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"instance\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"displayName\",\n                                      \"value\": \"Instance\"\n                                  },\n                                  {\n                                      \"id\": \"custom.align\",\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"short\"\n                                  },\n                                  {\n                                      \"id\": \"decimals\",\n                                      \"value\": 2\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"version\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"displayName\",\n                                      \"value\": \"Version\"\n                                  },\n                                  {\n                                      \"id\": \"custom.align\",\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"short\"\n                                  },\n                                  {\n                                      \"id\": \"decimals\",\n                                      \"value\": 2\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Value #A\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"displayName\",\n                                      \"value\": \"Count\"\n                                  },\n                                  {\n                                      \"id\": \"custom.align\",\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"short\"\n                                  },\n                                  {\n                                      \"id\": \"decimals\",\n                                      \"value\": 2\n                                  },\n                                  {\n                                      \"id\": \"custom.hidden\",\n                                      \"value\": \"true\"\n                                  }\n                              ]\n                          },\n                          {\n                              \"matcher\": {\n                                  \"id\": \"byName\",\n                                  \"options\": \"Value #B\"\n                              },\n                              \"properties\": [\n                                  {\n                                      \"id\": \"displayName\",\n                                      \"value\": \"Uptime\"\n                                  },\n                                  {\n                                      \"id\": \"custom.align\",\n                                      \"value\": null\n                                  },\n                                  {\n                                      \"id\": \"unit\",\n                                      \"value\": \"s\"\n                                  }\n                              ]\n                          }\n                      ]\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 1\n                  },\n                  \"id\": 2,\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"count by (cluster, job, instance, version) (prometheus_build_info{cluster=~\\\"$cluster\\\", job=~\\\"$job\\\", instance=~\\\"$instance\\\"})\",\n                          \"format\": \"table\",\n                          \"instant\": true,\n                          \"legendFormat\": \"\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"max by (cluster, job, instance) (time() - process_start_time_seconds{cluster=~\\\"$cluster\\\", job=~\\\"$job\\\", instance=~\\\"$instance\\\"})\",\n                          \"format\": \"table\",\n                          \"instant\": true,\n                          \"legendFormat\": \"\"\n                      }\n                  ],\n                  \"title\": \"Prometheus Stats\",\n                  \"type\": \"table\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 8\n                  },\n                  \"id\": 3,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Discovery\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\"\n                          },\n                          \"min\": 0,\n                          \"unit\": \"ms\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 4,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum(rate(prometheus_target_sync_length_seconds_sum{cluster=~\\\"$cluster\\\",job=~\\\"$job\\\",instance=~\\\"$instance\\\"}[5m])) by (cluster, job, scrape_job, instance) * 1e3\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"{{cluster}}:{{job}}:{{instance}}:{{scrape_job}}\"\n                      }\n                  ],\n                  \"title\": \"Target Sync\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"lineWidth\": 0,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"min\": 0,\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 9\n                  },\n                  \"id\": 5,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum by (cluster, job, instance) (prometheus_sd_discovered_targets{cluster=~\\\"$cluster\\\", job=~\\\"$job\\\",instance=~\\\"$instance\\\"})\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"{{cluster}}:{{job}}:{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Targets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 16\n                  },\n                  \"id\": 6,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Retrieval\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\"\n                          },\n                          \"min\": 0,\n                          \"unit\": \"ms\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 0,\n                      \"y\": 17\n                  },\n                  \"id\": 7,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(prometheus_target_interval_length_seconds_sum{cluster=~\\\"$cluster\\\", job=~\\\"$job\\\",instance=~\\\"$instance\\\"}[5m]) / rate(prometheus_target_interval_length_seconds_count{cluster=~\\\"$cluster\\\", job=~\\\"$job\\\",instance=~\\\"$instance\\\"}[5m]) * 1e3\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"{{cluster}}:{{job}}:{{instance}} {{interval}} configured\"\n                      }\n                  ],\n                  \"title\": \"Average Scrape Interval Duration\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"lineWidth\": 0,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"min\": 0,\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 8,\n                      \"y\": 17\n                  },\n                  \"id\": 8,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum by (cluster, job, instance) (rate(prometheus_target_scrapes_exceeded_body_size_limit_total{cluster=~\\\"$cluster\\\",job=~\\\"$job\\\",instance=~\\\"$instance\\\"}[1m]))\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"exceeded body size limit: {{cluster}} {{job}} {{instance}}\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum by (cluster, job, instance) (rate(prometheus_target_scrapes_exceeded_sample_limit_total{cluster=~\\\"$cluster\\\",job=~\\\"$job\\\",instance=~\\\"$instance\\\"}[1m]))\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"exceeded sample limit: {{cluster}} {{job}} {{instance}}\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum by (cluster, job, instance) (rate(prometheus_target_scrapes_sample_duplicate_timestamp_total{cluster=~\\\"$cluster\\\",job=~\\\"$job\\\",instance=~\\\"$instance\\\"}[1m]))\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"duplicate timestamp: {{cluster}} {{job}} {{instance}}\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum by (cluster, job, instance) (rate(prometheus_target_scrapes_sample_out_of_bounds_total{cluster=~\\\"$cluster\\\",job=~\\\"$job\\\",instance=~\\\"$instance\\\"}[1m]))\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"out of bounds: {{cluster}} {{job}} {{instance}}\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"sum by (cluster, job, instance) (rate(prometheus_target_scrapes_sample_out_of_order_total{cluster=~\\\"$cluster\\\",job=~\\\"$job\\\",instance=~\\\"$instance\\\"}[1m]))\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"out of order: {{cluster}} {{job}} {{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Scrape failures\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"lineWidth\": 0,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"min\": 0,\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 16,\n                      \"y\": 17\n                  },\n                  \"id\": 9,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(prometheus_tsdb_head_samples_appended_total{cluster=~\\\"$cluster\\\", job=~\\\"$job\\\",instance=~\\\"$instance\\\"}[5m])\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"{{cluster}} {{job}} {{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Appended Samples\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 24\n                  },\n                  \"id\": 10,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Storage\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"lineWidth\": 0,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"min\": 0,\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 25\n                  },\n                  \"id\": 11,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"prometheus_tsdb_head_series{cluster=~\\\"$cluster\\\",job=~\\\"$job\\\",instance=~\\\"$instance\\\"}\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"{{cluster}} {{job}} {{instance}} head series\"\n                      }\n                  ],\n                  \"title\": \"Head Series\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"lineWidth\": 0,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"min\": 0,\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 25\n                  },\n                  \"id\": 12,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"prometheus_tsdb_head_chunks{cluster=~\\\"$cluster\\\",job=~\\\"$job\\\",instance=~\\\"$instance\\\"}\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"{{cluster}} {{job}} {{instance}} head chunks\"\n                      }\n                  ],\n                  \"title\": \"Head Chunks\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"collapsed\": false,\n                  \"gridPos\": {\n                      \"h\": 1,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 32\n                  },\n                  \"id\": 13,\n                  \"panels\": [\n\n                  ],\n                  \"title\": \"Query\",\n                  \"type\": \"row\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"lineWidth\": 0,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"min\": 0,\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 33\n                  },\n                  \"id\": 14,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"rate(prometheus_engine_query_duration_seconds_count{cluster=~\\\"$cluster\\\",job=~\\\"$job\\\",instance=~\\\"$instance\\\",slice=\\\"inner_eval\\\"}[5m])\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"{{cluster}} {{job}} {{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Query Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"prometheus\",\n                      \"uid\": \"$datasource\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 100,\n                              \"lineWidth\": 0,\n                              \"showPoints\": \"never\",\n                              \"stacking\": {\n                                  \"mode\": \"normal\"\n                              }\n                          },\n                          \"min\": 0,\n                          \"unit\": \"ms\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 33\n                  },\n                  \"id\": 15,\n                  \"options\": {\n                      \"tooltip\": {\n                          \"mode\": \"multi\",\n                          \"sort\": \"desc\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"$datasource\"\n                          },\n                          \"expr\": \"max by (slice) (prometheus_engine_query_duration_seconds{quantile=\\\"0.9\\\",cluster=~\\\"$cluster\\\", job=~\\\"$job\\\",instance=~\\\"$instance\\\"}) * 1e3\",\n                          \"format\": \"time_series\",\n                          \"legendFormat\": \"{{slice}}\"\n                      }\n                  ],\n                  \"title\": \"Stage Duration\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"prometheus-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"allValue\": \".+\",\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": [\n                              \"$__all\"\n                          ],\n                          \"value\": [\n                              \"$__all\"\n                          ]\n                      },\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": \"cluster\",\n                      \"multi\": true,\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(prometheus_build_info{job=\\\"prometheus-k8s\\\",namespace=\\\"monitoring\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 2,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"allValue\": \".+\",\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"includeAll\": true,\n                      \"label\": \"job\",\n                      \"multi\": true,\n                      \"name\": \"job\",\n                      \"query\": \"label_values(prometheus_build_info{cluster=~\\\"$cluster\\\"}, job)\",\n                      \"refresh\": 2,\n                      \"sort\": 2,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"allValue\": \".+\",\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"includeAll\": true,\n                      \"label\": \"instance\",\n                      \"multi\": true,\n                      \"name\": \"instance\",\n                      \"query\": \"label_values(prometheus_build_info{cluster=~\\\"$cluster\\\", job=~\\\"$job\\\"}, instance)\",\n                      \"refresh\": 2,\n                      \"sort\": 2,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timepicker\": {\n              \"refresh_intervals\": [\n                  \"60s\"\n              ]\n          },\n          \"timezone\": \"utc\",\n          \"title\": \"Prometheus / Overview\",\n          \"uid\": \"9fa0d141-d019-4ad7-8bc5-42196ee308bd\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-prometheus\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    proxy.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 4,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(up{cluster=\\\"$cluster\\\", job=\\\"kube-proxy\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Up\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 10,\n                      \"x\": 4,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(kubeproxy_sync_proxy_rules_duration_seconds_count{cluster=\\\"$cluster\\\", job=\\\"kube-proxy\\\", instance=~\\\"$instance\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"rate\"\n                      }\n                  ],\n                  \"title\": \"Rules Sync Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 10,\n                      \"x\": 14,\n                      \"y\": 0\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99,rate(kubeproxy_sync_proxy_rules_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-proxy\\\", instance=~\\\"$instance\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Rules Sync Latency 99th Quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(kubeproxy_network_programming_duration_seconds_count{cluster=\\\"$cluster\\\", job=\\\"kube-proxy\\\", instance=~\\\"$instance\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"rate\"\n                      }\n                  ],\n                  \"title\": \"Network Programming Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 7\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(kubeproxy_network_programming_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-proxy\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (instance, le))\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Network Programming Latency 99th Quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{cluster=\\\"$cluster\\\",job=\\\"kube-proxy\\\", instance=~\\\"$instance\\\",code=~\\\"2..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"2xx\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{cluster=\\\"$cluster\\\",job=\\\"kube-proxy\\\", instance=~\\\"$instance\\\",code=~\\\"3..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"3xx\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{cluster=\\\"$cluster\\\",job=\\\"kube-proxy\\\", instance=~\\\"$instance\\\",code=~\\\"4..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"4xx\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{cluster=\\\"$cluster\\\",job=\\\"kube-proxy\\\", instance=~\\\"$instance\\\",code=~\\\"5..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"5xx\"\n                      }\n                  ],\n                  \"title\": \"Kube API Request Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 16,\n                      \"x\": 8,\n                      \"y\": 14\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-proxy\\\",instance=~\\\"$instance\\\",verb=\\\"POST\\\"}[$__rate_interval])) by (verb, le))\",\n                          \"legendFormat\": \"{{verb}}\"\n                      }\n                  ],\n                  \"title\": \"Post Request Latency 99th Quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-proxy\\\", instance=~\\\"$instance\\\", verb=\\\"GET\\\"}[$__rate_interval])) by (verb, le))\",\n                          \"legendFormat\": \"{{verb}}\"\n                      }\n                  ],\n                  \"title\": \"Get Request Latency 99th Quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 0,\n                      \"y\": 28\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"process_resident_memory_bytes{cluster=\\\"$cluster\\\", job=\\\"kube-proxy\\\",instance=~\\\"$instance\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Memory\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 8,\n                      \"y\": 28\n                  },\n                  \"id\": 10,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"rate(process_cpu_seconds_total{cluster=\\\"$cluster\\\", job=\\\"kube-proxy\\\",instance=~\\\"$instance\\\"}[$__rate_interval])\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"CPU usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 16,\n                      \"y\": 28\n                  },\n                  \"id\": 11,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"go_goroutines{cluster=\\\"$cluster\\\", job=\\\"kube-proxy\\\",instance=~\\\"$instance\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Goroutines\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kube-proxy\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"allValue\": \".+\",\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": \"instance\",\n                      \"name\": \"instance\",\n                      \"query\": \"label_values(up{job=\\\"kube-proxy\\\", cluster=\\\"$cluster\\\", job=\\\"kube-proxy\\\"}, instance)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Proxy\",\n          \"uid\": \"632e265de029684c40b21cb76bca4f94\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-proxy\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    scheduler.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"unit\": \"none\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 4,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"colorMode\": \"none\"\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(up{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\"})\",\n                          \"instant\": true\n                      }\n                  ],\n                  \"title\": \"Up\",\n                  \"type\": \"stat\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 10,\n                      \"x\": 4,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(scheduler_e2e_scheduling_duration_seconds_count{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (cluster, instance)\",\n                          \"legendFormat\": \"{{cluster}} {{instance}} e2e\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(scheduler_binding_duration_seconds_count{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (cluster, instance)\",\n                          \"legendFormat\": \"{{cluster}} {{instance}} binding\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(scheduler_scheduling_algorithm_duration_seconds_count{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (cluster, instance)\",\n                          \"legendFormat\": \"{{cluster}} {{instance}} scheduling algorithm\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(scheduler_volume_scheduling_duration_seconds_count{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\", instance=~\\\"$instance\\\"}[$__rate_interval])) by (cluster, instance)\",\n                          \"legendFormat\": \"{{cluster}} {{instance}} volume\"\n                      }\n                  ],\n                  \"title\": \"Scheduling Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 10,\n                      \"x\": 14,\n                      \"y\": 0\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (cluster, instance, le))\",\n                          \"legendFormat\": \"{{cluster}} {{instance}} e2e\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(scheduler_binding_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (cluster, instance, le))\",\n                          \"legendFormat\": \"{{cluster}} {{instance}} binding\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (cluster, instance, le))\",\n                          \"legendFormat\": \"{{cluster}} {{instance}} scheduling algorithm\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(scheduler_volume_scheduling_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\",instance=~\\\"$instance\\\"}[$__rate_interval])) by (cluster, instance, le))\",\n                          \"legendFormat\": \"{{cluster}} {{instance}} volume\"\n                      }\n                  ],\n                  \"title\": \"Scheduling latency 99th Quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 0,\n                      \"y\": 7\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\", instance=~\\\"$instance\\\",code=~\\\"2..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"2xx\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\", instance=~\\\"$instance\\\",code=~\\\"3..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"3xx\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\", instance=~\\\"$instance\\\",code=~\\\"4..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"4xx\"\n                      },\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sum(rate(rest_client_requests_total{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\", instance=~\\\"$instance\\\",code=~\\\"5..\\\"}[$__rate_interval]))\",\n                          \"legendFormat\": \"5xx\"\n                      }\n                  ],\n                  \"title\": \"Kube API Request Rate\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"ops\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 16,\n                      \"x\": 8,\n                      \"y\": 7\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\", instance=~\\\"$instance\\\", verb=\\\"POST\\\"}[$__rate_interval])) by (verb, le))\",\n                          \"legendFormat\": \"{{verb}}\"\n                      }\n                  ],\n                  \"title\": \"Post Request Latency 99th Quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"s\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 24,\n                      \"x\": 0,\n                      \"y\": 14\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"histogram_quantile(0.99, sum(rate(rest_client_request_duration_seconds_bucket{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\", instance=~\\\"$instance\\\", verb=\\\"GET\\\"}[$__rate_interval])) by (verb, le))\",\n                          \"legendFormat\": \"{{verb}}\"\n                      }\n                  ],\n                  \"title\": \"Get Request Latency 99th Quantile\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"bytes\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 0,\n                      \"y\": 21\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"process_resident_memory_bytes{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\", instance=~\\\"$instance\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Memory\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 8,\n                      \"y\": 21\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"rate(process_cpu_seconds_total{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\", instance=~\\\"$instance\\\"}[$__rate_interval])\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"CPU usage\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"short\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 7,\n                      \"w\": 8,\n                      \"x\": 16,\n                      \"y\": 21\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"go_goroutines{cluster=\\\"$cluster\\\", job=\\\"kube-scheduler\\\",instance=~\\\"$instance\\\"}\",\n                          \"legendFormat\": \"{{instance}}\"\n                      }\n                  ],\n                  \"title\": \"Goroutines\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(up{job=\\\"kube-scheduler\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"allValue\": \".+\",\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": \"instance\",\n                      \"name\": \"instance\",\n                      \"query\": \"label_values(up{job=\\\"kube-scheduler\\\", cluster=\\\"$cluster\\\"}, instance)\",\n                      \"refresh\": 2,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Scheduler\",\n          \"uid\": \"2e6b6a3b4bddf1427b3a55aa1311c656\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-scheduler\n    namespace: monitoring\n- apiVersion: v1\n  data:\n    workload-total.json: |-\n      {\n          \"editable\": false,\n          \"links\": [\n              {\n                  \"asDropdown\": true,\n                  \"includeVars\": true,\n                  \"keepTime\": true,\n                  \"tags\": [\n                      \"kubernetes-mixin\"\n                  ],\n                  \"targetBlank\": false,\n                  \"title\": \"Kubernetes\",\n                  \"type\": \"dashboards\"\n              }\n          ],\n          \"panels\": [\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"color\": {\n                              \"fixedColor\": \"green\",\n                              \"mode\": \"fixed\"\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 0\n                  },\n                  \"id\": 1,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"displayMode\": \"basic\",\n                      \"showUnfilled\": false\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Current Rate of Bytes Received\",\n                  \"type\": \"bargauge\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"color\": {\n                              \"fixedColor\": \"green\",\n                              \"mode\": \"fixed\"\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 0\n                  },\n                  \"id\": 2,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"displayMode\": \"basic\",\n                      \"showUnfilled\": false\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Current Rate of Bytes Transmitted\",\n                  \"type\": \"bargauge\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"color\": {\n                              \"fixedColor\": \"green\",\n                              \"mode\": \"fixed\"\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 9\n                  },\n                  \"id\": 3,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"displayMode\": \"basic\",\n                      \"showUnfilled\": false\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(avg(rate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Average Rate of Bytes Received\",\n                  \"type\": \"bargauge\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"color\": {\n                              \"fixedColor\": \"green\",\n                              \"mode\": \"fixed\"\n                          },\n                          \"unit\": \"Bps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 9\n                  },\n                  \"id\": 4,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"displayMode\": \"basic\",\n                      \"showUnfilled\": false\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(avg(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Average Rate of Bytes Transmitted\",\n                  \"type\": \"bargauge\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"binBps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 18\n                  },\n                  \"id\": 5,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_receive_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Receive Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"binBps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 18\n                  },\n                  \"id\": 6,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_transmit_bytes_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Transmit Bandwidth\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 27\n                  },\n                  \"id\": 7,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_receive_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 27\n                  },\n                  \"id\": 8,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_transmit_packets_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 0,\n                      \"y\": 36\n                  },\n                  \"id\": 9,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_receive_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Received Packets Dropped\",\n                  \"type\": \"timeseries\"\n              },\n              {\n                  \"datasource\": {\n                      \"type\": \"datasource\",\n                      \"uid\": \"-- Mixed --\"\n                  },\n                  \"fieldConfig\": {\n                      \"defaults\": {\n                          \"custom\": {\n                              \"fillOpacity\": 10,\n                              \"showPoints\": \"never\",\n                              \"spanNulls\": true\n                          },\n                          \"unit\": \"pps\"\n                      }\n                  },\n                  \"gridPos\": {\n                      \"h\": 9,\n                      \"w\": 12,\n                      \"x\": 12,\n                      \"y\": 36\n                  },\n                  \"id\": 10,\n                  \"interval\": \"1m\",\n                  \"options\": {\n                      \"legend\": {\n                          \"asTable\": true,\n                          \"calcs\": [\n                              \"lastNotNull\"\n                          ],\n                          \"displayMode\": \"table\",\n                          \"placement\": \"right\",\n                          \"showLegend\": true\n                      },\n                      \"tooltip\": {\n                          \"mode\": \"single\"\n                      }\n                  },\n                  \"pluginVersion\": \"v11.4.0\",\n                  \"targets\": [\n                      {\n                          \"datasource\": {\n                              \"type\": \"prometheus\",\n                              \"uid\": \"${datasource}\"\n                          },\n                          \"expr\": \"sort_desc(sum(rate(container_network_transmit_packets_dropped_total{job=\\\"kubelet\\\", metrics_path=\\\"/metrics/cadvisor\\\", cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\"}[$__rate_interval])\\n* on (namespace,pod)\\ngroup_left(workload,workload_type) namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\",namespace=~\\\"$namespace\\\", workload=~\\\"$workload\\\", workload_type=~\\\"$type\\\"}) by (pod))\\n\",\n                          \"legendFormat\": \"__auto\"\n                      }\n                  ],\n                  \"title\": \"Rate of Transmitted Packets Dropped\",\n                  \"type\": \"timeseries\"\n              }\n          ],\n          \"refresh\": \"10s\",\n          \"schemaVersion\": 39,\n          \"tags\": [\n              \"kubernetes-mixin\"\n          ],\n          \"templating\": {\n              \"list\": [\n                  {\n                      \"current\": {\n                          \"selected\": true,\n                          \"text\": \"default\",\n                          \"value\": \"default\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"Data source\",\n                      \"name\": \"datasource\",\n                      \"query\": \"prometheus\",\n                      \"regex\": \"\",\n                      \"type\": \"datasource\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"cluster\",\n                      \"name\": \"cluster\",\n                      \"query\": \"label_values(kube_pod_info{job=\\\"kube-state-metrics\\\"}, cluster)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"allValue\": \".+\",\n                      \"current\": {\n                          \"selected\": false,\n                          \"text\": \"kube-system\",\n                          \"value\": \"kube-system\"\n                      },\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": \"namespace\",\n                      \"name\": \"namespace\",\n                      \"query\": \"label_values(container_network_receive_packets_total{cluster=\\\"$cluster\\\"}, namespace)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"label\": \"workload\",\n                      \"name\": \"workload\",\n                      \"query\": \"label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=~\\\"$namespace\\\", workload=~\\\".+\\\"}, workload)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  },\n                  {\n                      \"allValue\": \".+\",\n                      \"datasource\": {\n                          \"type\": \"prometheus\",\n                          \"uid\": \"${datasource}\"\n                      },\n                      \"hide\": 0,\n                      \"includeAll\": true,\n                      \"label\": \"workload_type\",\n                      \"name\": \"type\",\n                      \"query\": \"label_values(namespace_workload_pod:kube_pod_owner:relabel{cluster=\\\"$cluster\\\", namespace=~\\\"$namespace\\\", workload=~\\\"$workload\\\"}, workload_type)\",\n                      \"refresh\": 2,\n                      \"sort\": 1,\n                      \"type\": \"query\"\n                  }\n              ]\n          },\n          \"time\": {\n              \"from\": \"now-1h\",\n              \"to\": \"now\"\n          },\n          \"timezone\": \"UTC\",\n          \"title\": \"Kubernetes / Networking / Workload\",\n          \"uid\": \"728bf77cc1166d2f3133bf25846876cc\"\n      }\n  kind: ConfigMap\n  metadata:\n    labels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 12.1.0\n    name: grafana-dashboard-workload-total\n    namespace: monitoring\nkind: ConfigMapList\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/grafana-dashboardSources.yaml",
    "content": "apiVersion: v1\ndata:\n  dashboards.yaml: |-\n    {\n        \"apiVersion\": 1,\n        \"providers\": [\n            {\n                \"folder\": \"Default\",\n                \"folderUid\": \"\",\n                \"name\": \"0\",\n                \"options\": {\n                    \"path\": \"/grafana-dashboard-definitions/0\"\n                },\n                \"orgId\": 1,\n                \"type\": \"file\"\n            }\n        ]\n    }\nkind: ConfigMap\nmetadata:\n  labels:\n    app.kubernetes.io/component: grafana\n    app.kubernetes.io/name: grafana\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 12.1.0\n  name: grafana-dashboards\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/grafana-deployment.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  labels:\n    app.kubernetes.io/component: grafana\n    app.kubernetes.io/name: grafana\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 12.1.0\n  name: grafana\n  namespace: monitoring\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n  template:\n    metadata:\n      annotations:\n        checksum/grafana-config: fbb6fa9bc8072c0f9758c30eac1a7ce6\n        checksum/grafana-dashboardproviders: 4c364bf7811a4eff194596a272550ae5\n        checksum/grafana-datasources: 34dc6d0eeebe415ac38992ae3518ab8e\n      labels:\n        app.kubernetes.io/component: grafana\n        app.kubernetes.io/name: grafana\n        app.kubernetes.io/part-of: kube-prometheus\n        app.kubernetes.io/version: 12.1.0\n    spec:\n      automountServiceAccountToken: false\n      containers:\n      - env: []\n        image: grafana/grafana:12.1.0\n        name: grafana\n        ports:\n        - containerPort: 3000\n          name: http\n        readinessProbe:\n          httpGet:\n            path: /api/health\n            port: http\n        resources:\n          limits:\n            cpu: 200m\n            memory: 200Mi\n          requests:\n            cpu: 100m\n            memory: 100Mi\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n          readOnlyRootFilesystem: true\n          seccompProfile:\n            type: RuntimeDefault\n        volumeMounts:\n        - mountPath: /var/lib/grafana\n          name: grafana-storage\n          readOnly: false\n        - mountPath: /etc/grafana/provisioning/datasources\n          name: grafana-datasources\n          readOnly: false\n        - mountPath: /etc/grafana/provisioning/dashboards\n          name: grafana-dashboards\n          readOnly: false\n        - mountPath: /tmp\n          name: tmp-plugins\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/alertmanager-overview\n          name: grafana-dashboard-alertmanager-overview\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/apiserver\n          name: grafana-dashboard-apiserver\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/cluster-total\n          name: grafana-dashboard-cluster-total\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/controller-manager\n          name: grafana-dashboard-controller-manager\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/grafana-overview\n          name: grafana-dashboard-grafana-overview\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/k8s-resources-cluster\n          name: grafana-dashboard-k8s-resources-cluster\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/k8s-resources-multicluster\n          name: grafana-dashboard-k8s-resources-multicluster\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/k8s-resources-namespace\n          name: grafana-dashboard-k8s-resources-namespace\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/k8s-resources-node\n          name: grafana-dashboard-k8s-resources-node\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/k8s-resources-pod\n          name: grafana-dashboard-k8s-resources-pod\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/k8s-resources-windows-cluster\n          name: grafana-dashboard-k8s-resources-windows-cluster\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/k8s-resources-windows-namespace\n          name: grafana-dashboard-k8s-resources-windows-namespace\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/k8s-resources-windows-pod\n          name: grafana-dashboard-k8s-resources-windows-pod\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/k8s-resources-workload\n          name: grafana-dashboard-k8s-resources-workload\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/k8s-resources-workloads-namespace\n          name: grafana-dashboard-k8s-resources-workloads-namespace\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/k8s-windows-cluster-rsrc-use\n          name: grafana-dashboard-k8s-windows-cluster-rsrc-use\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/k8s-windows-node-rsrc-use\n          name: grafana-dashboard-k8s-windows-node-rsrc-use\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/kubelet\n          name: grafana-dashboard-kubelet\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/namespace-by-pod\n          name: grafana-dashboard-namespace-by-pod\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/namespace-by-workload\n          name: grafana-dashboard-namespace-by-workload\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/node-cluster-rsrc-use\n          name: grafana-dashboard-node-cluster-rsrc-use\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/node-rsrc-use\n          name: grafana-dashboard-node-rsrc-use\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/nodes-aix\n          name: grafana-dashboard-nodes-aix\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/nodes-darwin\n          name: grafana-dashboard-nodes-darwin\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/nodes\n          name: grafana-dashboard-nodes\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/persistentvolumesusage\n          name: grafana-dashboard-persistentvolumesusage\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/pod-total\n          name: grafana-dashboard-pod-total\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/prometheus-remote-write\n          name: grafana-dashboard-prometheus-remote-write\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/prometheus\n          name: grafana-dashboard-prometheus\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/proxy\n          name: grafana-dashboard-proxy\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/scheduler\n          name: grafana-dashboard-scheduler\n          readOnly: false\n        - mountPath: /grafana-dashboard-definitions/0/workload-total\n          name: grafana-dashboard-workload-total\n          readOnly: false\n        - mountPath: /etc/grafana\n          name: grafana-config\n          readOnly: false\n      nodeSelector:\n        kubernetes.io/os: linux\n      securityContext:\n        fsGroup: 65534\n        runAsGroup: 65534\n        runAsNonRoot: true\n        runAsUser: 65534\n      serviceAccountName: grafana\n      volumes:\n      - emptyDir: {}\n        name: grafana-storage\n      - name: grafana-datasources\n        secret:\n          secretName: grafana-datasources\n      - configMap:\n          name: grafana-dashboards\n        name: grafana-dashboards\n      - emptyDir:\n          medium: Memory\n        name: tmp-plugins\n      - configMap:\n          name: grafana-dashboard-alertmanager-overview\n        name: grafana-dashboard-alertmanager-overview\n      - configMap:\n          name: grafana-dashboard-apiserver\n        name: grafana-dashboard-apiserver\n      - configMap:\n          name: grafana-dashboard-cluster-total\n        name: grafana-dashboard-cluster-total\n      - configMap:\n          name: grafana-dashboard-controller-manager\n        name: grafana-dashboard-controller-manager\n      - configMap:\n          name: grafana-dashboard-grafana-overview\n        name: grafana-dashboard-grafana-overview\n      - configMap:\n          name: grafana-dashboard-k8s-resources-cluster\n        name: grafana-dashboard-k8s-resources-cluster\n      - configMap:\n          name: grafana-dashboard-k8s-resources-multicluster\n        name: grafana-dashboard-k8s-resources-multicluster\n      - configMap:\n          name: grafana-dashboard-k8s-resources-namespace\n        name: grafana-dashboard-k8s-resources-namespace\n      - configMap:\n          name: grafana-dashboard-k8s-resources-node\n        name: grafana-dashboard-k8s-resources-node\n      - configMap:\n          name: grafana-dashboard-k8s-resources-pod\n        name: grafana-dashboard-k8s-resources-pod\n      - configMap:\n          name: grafana-dashboard-k8s-resources-windows-cluster\n        name: grafana-dashboard-k8s-resources-windows-cluster\n      - configMap:\n          name: grafana-dashboard-k8s-resources-windows-namespace\n        name: grafana-dashboard-k8s-resources-windows-namespace\n      - configMap:\n          name: grafana-dashboard-k8s-resources-windows-pod\n        name: grafana-dashboard-k8s-resources-windows-pod\n      - configMap:\n          name: grafana-dashboard-k8s-resources-workload\n        name: grafana-dashboard-k8s-resources-workload\n      - configMap:\n          name: grafana-dashboard-k8s-resources-workloads-namespace\n        name: grafana-dashboard-k8s-resources-workloads-namespace\n      - configMap:\n          name: grafana-dashboard-k8s-windows-cluster-rsrc-use\n        name: grafana-dashboard-k8s-windows-cluster-rsrc-use\n      - configMap:\n          name: grafana-dashboard-k8s-windows-node-rsrc-use\n        name: grafana-dashboard-k8s-windows-node-rsrc-use\n      - configMap:\n          name: grafana-dashboard-kubelet\n        name: grafana-dashboard-kubelet\n      - configMap:\n          name: grafana-dashboard-namespace-by-pod\n        name: grafana-dashboard-namespace-by-pod\n      - configMap:\n          name: grafana-dashboard-namespace-by-workload\n        name: grafana-dashboard-namespace-by-workload\n      - configMap:\n          name: grafana-dashboard-node-cluster-rsrc-use\n        name: grafana-dashboard-node-cluster-rsrc-use\n      - configMap:\n          name: grafana-dashboard-node-rsrc-use\n        name: grafana-dashboard-node-rsrc-use\n      - configMap:\n          name: grafana-dashboard-nodes-aix\n        name: grafana-dashboard-nodes-aix\n      - configMap:\n          name: grafana-dashboard-nodes-darwin\n        name: grafana-dashboard-nodes-darwin\n      - configMap:\n          name: grafana-dashboard-nodes\n        name: grafana-dashboard-nodes\n      - configMap:\n          name: grafana-dashboard-persistentvolumesusage\n        name: grafana-dashboard-persistentvolumesusage\n      - configMap:\n          name: grafana-dashboard-pod-total\n        name: grafana-dashboard-pod-total\n      - configMap:\n          name: grafana-dashboard-prometheus-remote-write\n        name: grafana-dashboard-prometheus-remote-write\n      - configMap:\n          name: grafana-dashboard-prometheus\n        name: grafana-dashboard-prometheus\n      - configMap:\n          name: grafana-dashboard-proxy\n        name: grafana-dashboard-proxy\n      - configMap:\n          name: grafana-dashboard-scheduler\n        name: grafana-dashboard-scheduler\n      - configMap:\n          name: grafana-dashboard-workload-total\n        name: grafana-dashboard-workload-total\n      - name: grafana-config\n        secret:\n          secretName: grafana-config\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/grafana-networkPolicy.yaml",
    "content": "apiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  labels:\n    app.kubernetes.io/component: grafana\n    app.kubernetes.io/name: grafana\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 12.1.0\n  name: grafana\n  namespace: monitoring\nspec:\n  egress:\n  - {}\n  ingress:\n  - from:\n    - podSelector:\n        matchLabels:\n          app.kubernetes.io/name: prometheus\n    ports:\n    - port: 3000\n      protocol: TCP\n  podSelector:\n    matchLabels:\n      app.kubernetes.io/component: grafana\n      app.kubernetes.io/name: grafana\n      app.kubernetes.io/part-of: kube-prometheus\n  policyTypes:\n  - Egress\n  - Ingress\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/grafana-prometheusRule.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  labels:\n    app.kubernetes.io/component: grafana\n    app.kubernetes.io/name: grafana\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 12.1.0\n    prometheus: k8s\n    role: alert-rules\n  name: grafana-rules\n  namespace: monitoring\nspec:\n  groups:\n  - name: GrafanaAlerts\n    rules:\n    - alert: GrafanaRequestsFailing\n      annotations:\n        message: '{{ $labels.namespace }}/{{ $labels.job }}/{{ $labels.handler }} is experiencing {{ $value | humanize }}% errors'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/grafana/grafanarequestsfailing\n      expr: |\n        100 * sum without (status_code) (namespace_job_handler_statuscode:grafana_http_request_duration_seconds_count:rate5m{handler!~\"/api/datasources/proxy/:id.*|/api/ds/query|/api/tsdb/query\", status_code=~\"5..\"})\n        /\n        sum without (status_code) (namespace_job_handler_statuscode:grafana_http_request_duration_seconds_count:rate5m{handler!~\"/api/datasources/proxy/:id.*|/api/ds/query|/api/tsdb/query\"})\n        > 50\n      for: 5m\n      labels:\n        severity: warning\n  - name: grafana_rules\n    rules:\n    - expr: |\n        sum by (namespace, job, handler, status_code) (rate(grafana_http_request_duration_seconds_count[5m]))\n      record: namespace_job_handler_statuscode:grafana_http_request_duration_seconds_count:rate5m\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/grafana-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    app.kubernetes.io/component: grafana\n    app.kubernetes.io/name: grafana\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 12.1.0\n  name: grafana\n  namespace: monitoring\nspec:\n  ports:\n  - name: http\n    port: 3000\n    targetPort: http\n  selector:\n    app.kubernetes.io/component: grafana\n    app.kubernetes.io/name: grafana\n    app.kubernetes.io/part-of: kube-prometheus\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/grafana-serviceAccount.yaml",
    "content": "apiVersion: v1\nautomountServiceAccountToken: false\nkind: ServiceAccount\nmetadata:\n  labels:\n    app.kubernetes.io/component: grafana\n    app.kubernetes.io/name: grafana\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 12.1.0\n  name: grafana\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/grafana-serviceMonitor.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  labels:\n    app.kubernetes.io/component: grafana\n    app.kubernetes.io/name: grafana\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 12.1.0\n  name: grafana\n  namespace: monitoring\nspec:\n  endpoints:\n  - interval: 15s\n    port: http\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: grafana\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubePrometheus-prometheusRule.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: kube-prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n    prometheus: k8s\n    role: alert-rules\n  name: kube-prometheus-rules\n  namespace: monitoring\nspec:\n  groups:\n  - name: general.rules\n    rules:\n    - alert: TargetDown\n      annotations:\n        description: '{{ printf \"%.4g\" $value }}% of the {{ $labels.job }}/{{ $labels.service }} targets in {{ $labels.namespace }} namespace are down.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/general/targetdown\n        summary: One or more targets are unreachable.\n      expr: 100 * (count(up == 0) BY (cluster, job, namespace, service) / count(up) BY (cluster, job, namespace, service)) > 10\n      for: 10m\n      labels:\n        severity: warning\n    - alert: Watchdog\n      annotations:\n        description: |\n          This is an alert meant to ensure that the entire alerting pipeline is functional.\n          This alert is always firing, therefore it should always be firing in Alertmanager\n          and always fire against a receiver. There are integrations with various notification\n          mechanisms that send a notification when this alert is not firing. For example the\n          \"DeadMansSnitch\" integration in PagerDuty.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/general/watchdog\n        summary: An alert that should always be firing to certify that Alertmanager is working properly.\n      expr: vector(1)\n      labels:\n        severity: none\n    - alert: InfoInhibitor\n      annotations:\n        description: |\n          This is an alert that is used to inhibit info alerts.\n          By themselves, the info-level alerts are sometimes very noisy, but they are relevant when combined with\n          other alerts.\n          This alert fires whenever there's a severity=\"info\" alert, and stops firing when another alert with a\n          severity of 'warning' or 'critical' starts firing on the same namespace.\n          This alert should be routed to a null receiver and configured to inhibit alerts with severity=\"info\".\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/general/infoinhibitor\n        summary: Info-level alert inhibition.\n      expr: ALERTS{severity = \"info\"} == 1 unless on(namespace) ALERTS{alertname != \"InfoInhibitor\", severity =~ \"warning|critical\", alertstate=\"firing\"} == 1\n      labels:\n        severity: none\n  - name: node-network\n    rules:\n    - alert: NodeNetworkInterfaceFlapping\n      annotations:\n        description: Network interface \"{{ $labels.device }}\" changing its up status often on node-exporter {{ $labels.namespace }}/{{ $labels.pod }}\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/general/nodenetworkinterfaceflapping\n        summary: Network interface is often changing its status\n      expr: |\n        changes(node_network_up{job=\"node-exporter\",device!~\"veth.+\"}[2m]) > 2\n      for: 2m\n      labels:\n        severity: warning\n  - name: kube-prometheus-node-recording.rules\n    rules:\n    - expr: sum(rate(node_cpu_seconds_total{mode!=\"idle\",mode!=\"iowait\",mode!=\"steal\"}[3m])) BY (instance)\n      record: instance:node_cpu:rate:sum\n    - expr: sum(rate(node_network_receive_bytes_total[3m])) BY (instance)\n      record: instance:node_network_receive_bytes:rate:sum\n    - expr: sum(rate(node_network_transmit_bytes_total[3m])) BY (instance)\n      record: instance:node_network_transmit_bytes:rate:sum\n    - expr: sum(rate(node_cpu_seconds_total{mode!=\"idle\",mode!=\"iowait\",mode!=\"steal\"}[5m])) WITHOUT (cpu, mode) / ON(instance) GROUP_LEFT() count(sum(node_cpu_seconds_total) BY (instance, cpu)) BY (instance)\n      record: instance:node_cpu:ratio\n    - expr: sum(rate(node_cpu_seconds_total{mode!=\"idle\",mode!=\"iowait\",mode!=\"steal\"}[5m]))\n      record: cluster:node_cpu:sum_rate5m\n    - expr: cluster:node_cpu:sum_rate5m / count(sum(node_cpu_seconds_total) BY (instance, cpu))\n      record: cluster:node_cpu:ratio\n  - name: kube-prometheus-general.rules\n    rules:\n    - expr: count without(instance, pod, node) (up == 1)\n      record: count:up1\n    - expr: count without(instance, pod, node) (up == 0)\n      record: count:up0\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubeStateMetrics-clusterRole.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: kube-state-metrics\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 2.16.0\n  name: kube-state-metrics\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - configmaps\n  - secrets\n  - nodes\n  - pods\n  - services\n  - serviceaccounts\n  - resourcequotas\n  - replicationcontrollers\n  - limitranges\n  - persistentvolumeclaims\n  - persistentvolumes\n  - namespaces\n  - endpoints\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - apps\n  resources:\n  - statefulsets\n  - daemonsets\n  - deployments\n  - replicasets\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - batch\n  resources:\n  - cronjobs\n  - jobs\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - autoscaling\n  resources:\n  - horizontalpodautoscalers\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - authentication.k8s.io\n  resources:\n  - tokenreviews\n  verbs:\n  - create\n- apiGroups:\n  - authorization.k8s.io\n  resources:\n  - subjectaccessreviews\n  verbs:\n  - create\n- apiGroups:\n  - policy\n  resources:\n  - poddisruptionbudgets\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - certificates.k8s.io\n  resources:\n  - certificatesigningrequests\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - discovery.k8s.io\n  resources:\n  - endpointslices\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - storage.k8s.io\n  resources:\n  - storageclasses\n  - volumeattachments\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - admissionregistration.k8s.io\n  resources:\n  - mutatingwebhookconfigurations\n  - validatingwebhookconfigurations\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - networking.k8s.io\n  resources:\n  - networkpolicies\n  - ingressclasses\n  - ingresses\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - coordination.k8s.io\n  resources:\n  - leases\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - rbac.authorization.k8s.io\n  resources:\n  - clusterrolebindings\n  - clusterroles\n  - rolebindings\n  - roles\n  verbs:\n  - list\n  - watch\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubeStateMetrics-clusterRoleBinding.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: kube-state-metrics\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 2.16.0\n  name: kube-state-metrics\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: kube-state-metrics\nsubjects:\n- kind: ServiceAccount\n  name: kube-state-metrics\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubeStateMetrics-deployment.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: kube-state-metrics\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 2.16.0\n  name: kube-state-metrics\n  namespace: monitoring\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: exporter\n      app.kubernetes.io/name: kube-state-metrics\n      app.kubernetes.io/part-of: kube-prometheus\n  template:\n    metadata:\n      annotations:\n        kubectl.kubernetes.io/default-container: kube-state-metrics\n      labels:\n        app.kubernetes.io/component: exporter\n        app.kubernetes.io/name: kube-state-metrics\n        app.kubernetes.io/part-of: kube-prometheus\n        app.kubernetes.io/version: 2.16.0\n    spec:\n      automountServiceAccountToken: true\n      containers:\n      - args:\n        - --host=127.0.0.1\n        - --port=8081\n        - --telemetry-host=127.0.0.1\n        - --telemetry-port=8082\n        image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.16.0\n        name: kube-state-metrics\n        resources:\n          limits:\n            cpu: 100m\n            memory: 250Mi\n          requests:\n            cpu: 10m\n            memory: 190Mi\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n          readOnlyRootFilesystem: true\n          runAsGroup: 65534\n          runAsNonRoot: true\n          runAsUser: 65534\n          seccompProfile:\n            type: RuntimeDefault\n      - args:\n        - --secure-listen-address=:8443\n        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305\n        - --upstream=http://127.0.0.1:8081/\n        image: quay.io/brancz/kube-rbac-proxy:v0.19.1\n        name: kube-rbac-proxy-main\n        ports:\n        - containerPort: 8443\n          name: https-main\n        resources:\n          limits:\n            cpu: 40m\n            memory: 40Mi\n          requests:\n            cpu: 20m\n            memory: 20Mi\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n          readOnlyRootFilesystem: true\n          runAsGroup: 65532\n          runAsNonRoot: true\n          runAsUser: 65532\n          seccompProfile:\n            type: RuntimeDefault\n      - args:\n        - --secure-listen-address=:9443\n        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305\n        - --upstream=http://127.0.0.1:8082/\n        image: quay.io/brancz/kube-rbac-proxy:v0.19.1\n        name: kube-rbac-proxy-self\n        ports:\n        - containerPort: 9443\n          name: https-self\n        resources:\n          limits:\n            cpu: 20m\n            memory: 40Mi\n          requests:\n            cpu: 10m\n            memory: 20Mi\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n          readOnlyRootFilesystem: true\n          runAsGroup: 65532\n          runAsNonRoot: true\n          runAsUser: 65532\n          seccompProfile:\n            type: RuntimeDefault\n      nodeSelector:\n        kubernetes.io/os: linux\n      serviceAccountName: kube-state-metrics\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubeStateMetrics-networkPolicy.yaml",
    "content": "apiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: kube-state-metrics\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 2.16.0\n  name: kube-state-metrics\n  namespace: monitoring\nspec:\n  egress:\n  - {}\n  ingress:\n  - from:\n    - podSelector:\n        matchLabels:\n          app.kubernetes.io/name: prometheus\n    ports:\n    - port: 8443\n      protocol: TCP\n    - port: 9443\n      protocol: TCP\n  podSelector:\n    matchLabels:\n      app.kubernetes.io/component: exporter\n      app.kubernetes.io/name: kube-state-metrics\n      app.kubernetes.io/part-of: kube-prometheus\n  policyTypes:\n  - Egress\n  - Ingress\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubeStateMetrics-prometheusRule.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: kube-state-metrics\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 2.16.0\n    prometheus: k8s\n    role: alert-rules\n  name: kube-state-metrics-rules\n  namespace: monitoring\nspec:\n  groups:\n  - name: kube-state-metrics\n    rules:\n    - alert: KubeStateMetricsListErrors\n      annotations:\n        description: kube-state-metrics is experiencing errors at an elevated rate in list operations. This is likely causing it to not be able to expose metrics about Kubernetes objects correctly or at all.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kube-state-metrics/kubestatemetricslisterrors\n        summary: kube-state-metrics is experiencing errors in list operations.\n      expr: |\n        (sum(rate(kube_state_metrics_list_total{job=\"kube-state-metrics\",result=\"error\"}[5m])) by (cluster)\n          /\n        sum(rate(kube_state_metrics_list_total{job=\"kube-state-metrics\"}[5m])) by (cluster))\n        > 0.01\n      for: 15m\n      labels:\n        severity: critical\n    - alert: KubeStateMetricsWatchErrors\n      annotations:\n        description: kube-state-metrics is experiencing errors at an elevated rate in watch operations. This is likely causing it to not be able to expose metrics about Kubernetes objects correctly or at all.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kube-state-metrics/kubestatemetricswatcherrors\n        summary: kube-state-metrics is experiencing errors in watch operations.\n      expr: |\n        (sum(rate(kube_state_metrics_watch_total{job=\"kube-state-metrics\",result=\"error\"}[5m])) by (cluster)\n          /\n        sum(rate(kube_state_metrics_watch_total{job=\"kube-state-metrics\"}[5m])) by (cluster))\n        > 0.01\n      for: 15m\n      labels:\n        severity: critical\n    - alert: KubeStateMetricsShardingMismatch\n      annotations:\n        description: kube-state-metrics pods are running with different --total-shards configuration, some Kubernetes objects may be exposed multiple times or not exposed at all.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kube-state-metrics/kubestatemetricsshardingmismatch\n        summary: kube-state-metrics sharding is misconfigured.\n      expr: |\n        stdvar (kube_state_metrics_total_shards{job=\"kube-state-metrics\"}) by (cluster) != 0\n      for: 15m\n      labels:\n        severity: critical\n    - alert: KubeStateMetricsShardsMissing\n      annotations:\n        description: kube-state-metrics shards are missing, some Kubernetes objects are not being exposed.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kube-state-metrics/kubestatemetricsshardsmissing\n        summary: kube-state-metrics shards are missing.\n      expr: |\n        2^max(kube_state_metrics_total_shards{job=\"kube-state-metrics\"}) by (cluster) - 1\n          -\n        sum( 2 ^ max by (cluster, shard_ordinal) (kube_state_metrics_shard_ordinal{job=\"kube-state-metrics\"}) ) by (cluster)\n        != 0\n      for: 15m\n      labels:\n        severity: critical\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubeStateMetrics-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: kube-state-metrics\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 2.16.0\n  name: kube-state-metrics\n  namespace: monitoring\nspec:\n  clusterIP: None\n  ports:\n  - name: https-main\n    port: 8443\n    targetPort: https-main\n  - name: https-self\n    port: 9443\n    targetPort: https-self\n  selector:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: kube-state-metrics\n    app.kubernetes.io/part-of: kube-prometheus\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubeStateMetrics-serviceAccount.yaml",
    "content": "apiVersion: v1\nautomountServiceAccountToken: false\nkind: ServiceAccount\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: kube-state-metrics\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 2.16.0\n  name: kube-state-metrics\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubeStateMetrics-serviceMonitor.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: kube-state-metrics\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 2.16.0\n  name: kube-state-metrics\n  namespace: monitoring\nspec:\n  endpoints:\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    honorLabels: true\n    interval: 30s\n    metricRelabelings:\n    - action: drop\n      regex: kube_(endpoint_(address_not_ready|address_available|ports))\n      sourceLabels:\n      - __name__\n    port: https-main\n    relabelings:\n    - action: labeldrop\n      regex: (pod|service|endpoint|namespace)\n    scheme: https\n    scrapeTimeout: 30s\n    tlsConfig:\n      insecureSkipVerify: true\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    interval: 30s\n    port: https-self\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  jobLabel: app.kubernetes.io/name\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: exporter\n      app.kubernetes.io/name: kube-state-metrics\n      app.kubernetes.io/part-of: kube-prometheus\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubernetesControlPlane-prometheusRule.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  labels:\n    app.kubernetes.io/component: kubernetes\n    app.kubernetes.io/name: kube-prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n    prometheus: k8s\n    role: alert-rules\n  name: kubernetes-monitoring-rules\n  namespace: monitoring\nspec:\n  groups:\n  - name: kubernetes-apps\n    rules:\n    - alert: KubePodCrashLooping\n      annotations:\n        description: 'Pod {{ $labels.namespace }}/{{ $labels.pod }} ({{ $labels.container }}) is in waiting state (reason: \"CrashLoopBackOff\") on cluster {{ $labels.cluster }}.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepodcrashlooping\n        summary: Pod is crash looping.\n      expr: |\n        max_over_time(kube_pod_container_status_waiting_reason{reason=\"CrashLoopBackOff\", job=\"kube-state-metrics\"}[5m]) >= 1\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubePodNotReady\n      annotations:\n        description: Pod {{ $labels.namespace }}/{{ $labels.pod }} has been in a non-ready state for longer than 15 minutes on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepodnotready\n        summary: Pod has been in a non-ready state for more than 15 minutes.\n      expr: |\n        sum by (namespace, pod, cluster) (\n          max by(namespace, pod, cluster) (\n            kube_pod_status_phase{job=\"kube-state-metrics\", phase=~\"Pending|Unknown|Failed\"}\n          ) * on(namespace, pod, cluster) group_left(owner_kind) topk by(namespace, pod, cluster) (\n            1, max by(namespace, pod, owner_kind, cluster) (kube_pod_owner{owner_kind!=\"Job\"})\n          )\n        ) > 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeDeploymentGenerationMismatch\n      annotations:\n        description: Deployment generation for {{ $labels.namespace }}/{{ $labels.deployment }} does not match, this indicates that the Deployment has failed but has not been rolled back on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedeploymentgenerationmismatch\n        summary: Deployment generation mismatch due to possible roll-back\n      expr: |\n        kube_deployment_status_observed_generation{job=\"kube-state-metrics\"}\n          !=\n        kube_deployment_metadata_generation{job=\"kube-state-metrics\"}\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeDeploymentReplicasMismatch\n      annotations:\n        description: Deployment {{ $labels.namespace }}/{{ $labels.deployment }} has not matched the expected number of replicas for longer than 15 minutes on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedeploymentreplicasmismatch\n        summary: Deployment has not matched the expected number of replicas.\n      expr: |\n        (\n          kube_deployment_spec_replicas{job=\"kube-state-metrics\"}\n            >\n          kube_deployment_status_replicas_available{job=\"kube-state-metrics\"}\n        ) and (\n          changes(kube_deployment_status_replicas_updated{job=\"kube-state-metrics\"}[10m])\n            ==\n          0\n        )\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeDeploymentRolloutStuck\n      annotations:\n        description: Rollout of deployment {{ $labels.namespace }}/{{ $labels.deployment }} is not progressing for longer than 15 minutes on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedeploymentrolloutstuck\n        summary: Deployment rollout is not progressing.\n      expr: |\n        kube_deployment_status_condition{condition=\"Progressing\", status=\"false\",job=\"kube-state-metrics\"}\n        != 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeStatefulSetReplicasMismatch\n      annotations:\n        description: StatefulSet {{ $labels.namespace }}/{{ $labels.statefulset }} has not matched the expected number of replicas for longer than 15 minutes on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubestatefulsetreplicasmismatch\n        summary: StatefulSet has not matched the expected number of replicas.\n      expr: |\n        (\n          kube_statefulset_status_replicas_ready{job=\"kube-state-metrics\"}\n            !=\n          kube_statefulset_replicas{job=\"kube-state-metrics\"}\n        ) and (\n          changes(kube_statefulset_status_replicas_updated{job=\"kube-state-metrics\"}[10m])\n            ==\n          0\n        )\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeStatefulSetGenerationMismatch\n      annotations:\n        description: StatefulSet generation for {{ $labels.namespace }}/{{ $labels.statefulset }} does not match, this indicates that the StatefulSet has failed but has not been rolled back on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubestatefulsetgenerationmismatch\n        summary: StatefulSet generation mismatch due to possible roll-back\n      expr: |\n        kube_statefulset_status_observed_generation{job=\"kube-state-metrics\"}\n          !=\n        kube_statefulset_metadata_generation{job=\"kube-state-metrics\"}\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeStatefulSetUpdateNotRolledOut\n      annotations:\n        description: StatefulSet {{ $labels.namespace }}/{{ $labels.statefulset }} update has not been rolled out on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubestatefulsetupdatenotrolledout\n        summary: StatefulSet update has not been rolled out.\n      expr: |\n        (\n          max by(namespace, statefulset, job, cluster) (\n            kube_statefulset_status_current_revision{job=\"kube-state-metrics\"}\n              unless\n            kube_statefulset_status_update_revision{job=\"kube-state-metrics\"}\n          )\n            * on(namespace, statefulset, job, cluster)\n          (\n            kube_statefulset_replicas{job=\"kube-state-metrics\"}\n              !=\n            kube_statefulset_status_replicas_updated{job=\"kube-state-metrics\"}\n          )\n        )  and on(namespace, statefulset, job, cluster) (\n          changes(kube_statefulset_status_replicas_updated{job=\"kube-state-metrics\"}[5m])\n            ==\n          0\n        )\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeDaemonSetRolloutStuck\n      annotations:\n        description: DaemonSet {{ $labels.namespace }}/{{ $labels.daemonset }} has not finished or progressed for at least 15m on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedaemonsetrolloutstuck\n        summary: DaemonSet rollout is stuck.\n      expr: |\n        (\n          (\n            kube_daemonset_status_current_number_scheduled{job=\"kube-state-metrics\"}\n              !=\n            kube_daemonset_status_desired_number_scheduled{job=\"kube-state-metrics\"}\n          ) or (\n            kube_daemonset_status_number_misscheduled{job=\"kube-state-metrics\"}\n              !=\n            0\n          ) or (\n            kube_daemonset_status_updated_number_scheduled{job=\"kube-state-metrics\"}\n              !=\n            kube_daemonset_status_desired_number_scheduled{job=\"kube-state-metrics\"}\n          ) or (\n            kube_daemonset_status_number_available{job=\"kube-state-metrics\"}\n              !=\n            kube_daemonset_status_desired_number_scheduled{job=\"kube-state-metrics\"}\n          )\n        ) and (\n          changes(kube_daemonset_status_updated_number_scheduled{job=\"kube-state-metrics\"}[5m])\n            ==\n          0\n        )\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeContainerWaiting\n      annotations:\n        description: 'pod/{{ $labels.pod }} in namespace {{ $labels.namespace }} on container {{ $labels.container}} has been in waiting state for longer than 1 hour. (reason: \"{{ $labels.reason }}\") on cluster {{ $labels.cluster }}.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubecontainerwaiting\n        summary: Pod container waiting longer than 1 hour\n      expr: |\n        kube_pod_container_status_waiting_reason{reason!=\"CrashLoopBackOff\", job=\"kube-state-metrics\"} > 0\n      for: 1h\n      labels:\n        severity: warning\n    - alert: KubeDaemonSetNotScheduled\n      annotations:\n        description: '{{ $value }} Pods of DaemonSet {{ $labels.namespace }}/{{ $labels.daemonset }} are not scheduled on cluster {{ $labels.cluster }}.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedaemonsetnotscheduled\n        summary: DaemonSet pods are not scheduled.\n      expr: |\n        kube_daemonset_status_desired_number_scheduled{job=\"kube-state-metrics\"}\n          -\n        kube_daemonset_status_current_number_scheduled{job=\"kube-state-metrics\"} > 0\n      for: 10m\n      labels:\n        severity: warning\n    - alert: KubeDaemonSetMisScheduled\n      annotations:\n        description: '{{ $value }} Pods of DaemonSet {{ $labels.namespace }}/{{ $labels.daemonset }} are running where they are not supposed to run on cluster {{ $labels.cluster }}.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubedaemonsetmisscheduled\n        summary: DaemonSet pods are misscheduled.\n      expr: |\n        kube_daemonset_status_number_misscheduled{job=\"kube-state-metrics\"} > 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeJobNotCompleted\n      annotations:\n        description: Job {{ $labels.namespace }}/{{ $labels.job_name }} is taking more than {{ \"43200\" | humanizeDuration }} to complete on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubejobnotcompleted\n        summary: Job did not complete in time\n      expr: |\n        time() - max by(namespace, job_name, cluster) (kube_job_status_start_time{job=\"kube-state-metrics\"}\n          and\n        kube_job_status_active{job=\"kube-state-metrics\"} > 0) > 43200\n      labels:\n        severity: warning\n    - alert: KubeJobFailed\n      annotations:\n        description: Job {{ $labels.namespace }}/{{ $labels.job_name }} failed to complete. Removing failed job after investigation should clear this alert on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubejobfailed\n        summary: Job failed to complete.\n      expr: |\n        kube_job_failed{job=\"kube-state-metrics\"}  > 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeHpaReplicasMismatch\n      annotations:\n        description: HPA {{ $labels.namespace }}/{{ $labels.horizontalpodautoscaler  }} has not matched the desired number of replicas for longer than 15 minutes on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubehpareplicasmismatch\n        summary: HPA has not matched desired number of replicas.\n      expr: |\n        (kube_horizontalpodautoscaler_status_desired_replicas{job=\"kube-state-metrics\"}\n          !=\n        kube_horizontalpodautoscaler_status_current_replicas{job=\"kube-state-metrics\"})\n          and\n        (kube_horizontalpodautoscaler_status_current_replicas{job=\"kube-state-metrics\"}\n          >\n        kube_horizontalpodautoscaler_spec_min_replicas{job=\"kube-state-metrics\"})\n          and\n        (kube_horizontalpodautoscaler_status_current_replicas{job=\"kube-state-metrics\"}\n          <\n        kube_horizontalpodautoscaler_spec_max_replicas{job=\"kube-state-metrics\"})\n          and\n        changes(kube_horizontalpodautoscaler_status_current_replicas{job=\"kube-state-metrics\"}[15m]) == 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeHpaMaxedOut\n      annotations:\n        description: HPA {{ $labels.namespace }}/{{ $labels.horizontalpodautoscaler  }} has been running at max replicas for longer than 15 minutes on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubehpamaxedout\n        summary: HPA is running at max replicas\n      expr: |\n        kube_horizontalpodautoscaler_status_current_replicas{job=\"kube-state-metrics\"}\n          ==\n        kube_horizontalpodautoscaler_spec_max_replicas{job=\"kube-state-metrics\"}\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubePdbNotEnoughHealthyPods\n      annotations:\n        description: PDB {{ $labels.cluster }}/{{ $labels.namespace }}/{{ $labels.poddisruptionbudget }} expects {{ $value }} more healthy pods. The desired number of healthy pods has not been met for at least 15m.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepdbnotenoughhealthypods\n        summary: PDB does not have enough healthy pods.\n      expr: |\n        (\n          kube_poddisruptionbudget_status_desired_healthy{job=\"kube-state-metrics\"}\n          -\n          kube_poddisruptionbudget_status_current_healthy{job=\"kube-state-metrics\"}\n        )\n        > 0\n      for: 15m\n      labels:\n        severity: warning\n  - name: kubernetes-resources\n    rules:\n    - alert: KubeCPUOvercommit\n      annotations:\n        description: Cluster {{ $labels.cluster }} has overcommitted CPU resource requests for Pods by {{ printf \"%.2f\" $value }} CPU shares and cannot tolerate node failure.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubecpuovercommit\n        summary: Cluster has overcommitted CPU resource requests.\n      expr: |\n        # Non-HA clusters.\n        (\n          (\n            sum by(cluster) (namespace_cpu:kube_pod_container_resource_requests:sum{})\n            -\n            sum by(cluster) (kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"cpu\"}) > 0\n          )\n          and\n          count by (cluster) (max by (cluster, node) (kube_node_role{job=\"kube-state-metrics\", role=\"control-plane\"})) < 3\n        )\n        or\n        # HA clusters.\n        (\n          sum by(cluster) (namespace_cpu:kube_pod_container_resource_requests:sum{})\n          -\n          (\n            # Skip clusters with only one allocatable node.\n            (\n              sum by (cluster) (kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"cpu\"})\n              -\n              max by (cluster) (kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"cpu\"})\n            ) > 0\n          ) > 0\n        )\n      for: 10m\n      labels:\n        severity: warning\n    - alert: KubeMemoryOvercommit\n      annotations:\n        description: Cluster {{ $labels.cluster }} has overcommitted memory resource requests for Pods by {{ $value | humanize }} bytes and cannot tolerate node failure.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubememoryovercommit\n        summary: Cluster has overcommitted memory resource requests.\n      expr: |\n        # Non-HA clusters.\n        (\n          (\n            sum by(cluster) (namespace_memory:kube_pod_container_resource_requests:sum{})\n            -\n            sum by(cluster) (kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"memory\"}) > 0\n          )\n          and\n          count by (cluster) (max by (cluster, node) (kube_node_role{job=\"kube-state-metrics\", role=\"control-plane\"})) < 3\n        )\n        or\n        # HA clusters.\n        (\n          sum by(cluster) (namespace_memory:kube_pod_container_resource_requests:sum{})\n          -\n          (\n            # Skip clusters with only one allocatable node.\n            (\n              sum by (cluster) (kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"memory\"})\n              -\n              max by (cluster) (kube_node_status_allocatable{job=\"kube-state-metrics\",resource=\"memory\"})\n            ) > 0\n          ) > 0\n        )\n      for: 10m\n      labels:\n        severity: warning\n    - alert: KubeCPUQuotaOvercommit\n      annotations:\n        description: Cluster {{ $labels.cluster }} has overcommitted CPU resource requests for Namespaces.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubecpuquotaovercommit\n        summary: Cluster has overcommitted CPU resource requests.\n      expr: |\n        sum by(cluster) (\n          min without(resource) (kube_resourcequota{job=\"kube-state-metrics\", type=\"hard\", resource=~\"(cpu|requests.cpu)\"})\n        )\n        /\n        sum by(cluster) (\n          kube_node_status_allocatable{resource=\"cpu\", job=\"kube-state-metrics\"}\n        ) > 1.5\n      for: 5m\n      labels:\n        severity: warning\n    - alert: KubeMemoryQuotaOvercommit\n      annotations:\n        description: Cluster {{ $labels.cluster }} has overcommitted memory resource requests for Namespaces.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubememoryquotaovercommit\n        summary: Cluster has overcommitted memory resource requests.\n      expr: |\n        sum by(cluster) (\n          min without(resource) (kube_resourcequota{job=\"kube-state-metrics\", type=\"hard\", resource=~\"(memory|requests.memory)\"})\n        )\n        /\n        sum by(cluster) (\n          kube_node_status_allocatable{resource=\"memory\", job=\"kube-state-metrics\"}\n        ) > 1.5\n      for: 5m\n      labels:\n        severity: warning\n    - alert: KubeQuotaAlmostFull\n      annotations:\n        description: Namespace {{ $labels.namespace }} is using {{ $value | humanizePercentage }} of its {{ $labels.resource }} quota on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubequotaalmostfull\n        summary: Namespace quota is going to be full.\n      expr: |\n        kube_resourcequota{job=\"kube-state-metrics\", type=\"used\"}\n          / ignoring(instance, job, type)\n        (kube_resourcequota{job=\"kube-state-metrics\", type=\"hard\"} > 0)\n          > 0.9 < 1\n      for: 15m\n      labels:\n        severity: info\n    - alert: KubeQuotaFullyUsed\n      annotations:\n        description: Namespace {{ $labels.namespace }} is using {{ $value | humanizePercentage }} of its {{ $labels.resource }} quota on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubequotafullyused\n        summary: Namespace quota is fully used.\n      expr: |\n        kube_resourcequota{job=\"kube-state-metrics\", type=\"used\"}\n          / ignoring(instance, job, type)\n        (kube_resourcequota{job=\"kube-state-metrics\", type=\"hard\"} > 0)\n          == 1\n      for: 15m\n      labels:\n        severity: info\n    - alert: KubeQuotaExceeded\n      annotations:\n        description: Namespace {{ $labels.namespace }} is using {{ $value | humanizePercentage }} of its {{ $labels.resource }} quota on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubequotaexceeded\n        summary: Namespace quota has exceeded the limits.\n      expr: |\n        kube_resourcequota{job=\"kube-state-metrics\", type=\"used\"}\n          / ignoring(instance, job, type)\n        (kube_resourcequota{job=\"kube-state-metrics\", type=\"hard\"} > 0)\n          > 1\n      for: 15m\n      labels:\n        severity: warning\n    - alert: CPUThrottlingHigh\n      annotations:\n        description: '{{ $value | humanizePercentage }} throttling of CPU in namespace {{ $labels.namespace }} for container {{ $labels.container }} in pod {{ $labels.pod }} on cluster {{ $labels.cluster }}.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/cputhrottlinghigh\n        summary: Processes experience elevated CPU throttling.\n      expr: |\n        sum(increase(container_cpu_cfs_throttled_periods_total{container!=\"\", job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", }[5m])) without (id, metrics_path, name, image, endpoint, job, node)\n          / on (cluster, namespace, pod, container, instance) group_left\n        sum(increase(container_cpu_cfs_periods_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", }[5m])) without (id, metrics_path, name, image, endpoint, job, node)\n          > ( 25 / 100 )\n      for: 15m\n      labels:\n        severity: info\n  - name: kubernetes-storage\n    rules:\n    - alert: KubePersistentVolumeFillingUp\n      annotations:\n        description: The PersistentVolume claimed by {{ $labels.persistentvolumeclaim }} in Namespace {{ $labels.namespace }} {{ with $labels.cluster -}} on Cluster {{ . }} {{- end }} is only {{ $value | humanizePercentage }} free.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepersistentvolumefillingup\n        summary: PersistentVolume is filling up.\n      expr: |\n        (\n          kubelet_volume_stats_available_bytes{job=\"kubelet\", metrics_path=\"/metrics\"}\n            /\n          kubelet_volume_stats_capacity_bytes{job=\"kubelet\", metrics_path=\"/metrics\"}\n        ) < 0.03\n        and\n        kubelet_volume_stats_used_bytes{job=\"kubelet\", metrics_path=\"/metrics\"} > 0\n        unless on(cluster, namespace, persistentvolumeclaim)\n        kube_persistentvolumeclaim_access_mode{ access_mode=\"ReadOnlyMany\"} == 1\n        unless on(cluster, namespace, persistentvolumeclaim)\n        kube_persistentvolumeclaim_labels{label_excluded_from_alerts=\"true\"} == 1\n      for: 1m\n      labels:\n        severity: critical\n    - alert: KubePersistentVolumeFillingUp\n      annotations:\n        description: Based on recent sampling, the PersistentVolume claimed by {{ $labels.persistentvolumeclaim }} in Namespace {{ $labels.namespace }} {{ with $labels.cluster -}} on Cluster {{ . }} {{- end }} is expected to fill up within four days. Currently {{ $value | humanizePercentage }} is available.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepersistentvolumefillingup\n        summary: PersistentVolume is filling up.\n      expr: |\n        (\n          kubelet_volume_stats_available_bytes{job=\"kubelet\", metrics_path=\"/metrics\"}\n            /\n          kubelet_volume_stats_capacity_bytes{job=\"kubelet\", metrics_path=\"/metrics\"}\n        ) < 0.15\n        and\n        kubelet_volume_stats_used_bytes{job=\"kubelet\", metrics_path=\"/metrics\"} > 0\n        and\n        predict_linear(kubelet_volume_stats_available_bytes{job=\"kubelet\", metrics_path=\"/metrics\"}[6h], 4 * 24 * 3600) < 0\n        unless on(cluster, namespace, persistentvolumeclaim)\n        kube_persistentvolumeclaim_access_mode{ access_mode=\"ReadOnlyMany\"} == 1\n        unless on(cluster, namespace, persistentvolumeclaim)\n        kube_persistentvolumeclaim_labels{label_excluded_from_alerts=\"true\"} == 1\n      for: 1h\n      labels:\n        severity: warning\n    - alert: KubePersistentVolumeInodesFillingUp\n      annotations:\n        description: The PersistentVolume claimed by {{ $labels.persistentvolumeclaim }} in Namespace {{ $labels.namespace }} {{ with $labels.cluster -}} on Cluster {{ . }} {{- end }} only has {{ $value | humanizePercentage }} free inodes.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepersistentvolumeinodesfillingup\n        summary: PersistentVolumeInodes are filling up.\n      expr: |\n        (\n          kubelet_volume_stats_inodes_free{job=\"kubelet\", metrics_path=\"/metrics\"}\n            /\n          kubelet_volume_stats_inodes{job=\"kubelet\", metrics_path=\"/metrics\"}\n        ) < 0.03\n        and\n        kubelet_volume_stats_inodes_used{job=\"kubelet\", metrics_path=\"/metrics\"} > 0\n        unless on(cluster, namespace, persistentvolumeclaim)\n        kube_persistentvolumeclaim_access_mode{ access_mode=\"ReadOnlyMany\"} == 1\n        unless on(cluster, namespace, persistentvolumeclaim)\n        kube_persistentvolumeclaim_labels{label_excluded_from_alerts=\"true\"} == 1\n      for: 1m\n      labels:\n        severity: critical\n    - alert: KubePersistentVolumeInodesFillingUp\n      annotations:\n        description: Based on recent sampling, the PersistentVolume claimed by {{ $labels.persistentvolumeclaim }} in Namespace {{ $labels.namespace }} {{ with $labels.cluster -}} on Cluster {{ . }} {{- end }} is expected to run out of inodes within four days. Currently {{ $value | humanizePercentage }} of its inodes are free.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepersistentvolumeinodesfillingup\n        summary: PersistentVolumeInodes are filling up.\n      expr: |\n        (\n          kubelet_volume_stats_inodes_free{job=\"kubelet\", metrics_path=\"/metrics\"}\n            /\n          kubelet_volume_stats_inodes{job=\"kubelet\", metrics_path=\"/metrics\"}\n        ) < 0.15\n        and\n        kubelet_volume_stats_inodes_used{job=\"kubelet\", metrics_path=\"/metrics\"} > 0\n        and\n        predict_linear(kubelet_volume_stats_inodes_free{job=\"kubelet\", metrics_path=\"/metrics\"}[6h], 4 * 24 * 3600) < 0\n        unless on(cluster, namespace, persistentvolumeclaim)\n        kube_persistentvolumeclaim_access_mode{ access_mode=\"ReadOnlyMany\"} == 1\n        unless on(cluster, namespace, persistentvolumeclaim)\n        kube_persistentvolumeclaim_labels{label_excluded_from_alerts=\"true\"} == 1\n      for: 1h\n      labels:\n        severity: warning\n    - alert: KubePersistentVolumeErrors\n      annotations:\n        description: The persistent volume {{ $labels.persistentvolume }} {{ with $labels.cluster -}} on Cluster {{ . }} {{- end }} has status {{ $labels.phase }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepersistentvolumeerrors\n        summary: PersistentVolume is having issues with provisioning.\n      expr: |\n        kube_persistentvolume_status_phase{phase=~\"Failed|Pending\",job=\"kube-state-metrics\"} > 0\n      for: 5m\n      labels:\n        severity: critical\n  - name: kubernetes-system\n    rules:\n    - alert: KubeVersionMismatch\n      annotations:\n        description: There are {{ $value }} different semantic versions of Kubernetes components running on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeversionmismatch\n        summary: Different semantic versions of Kubernetes components running.\n      expr: |\n        count by (cluster) (count by (git_version, cluster) (label_replace(kubernetes_build_info{job!~\"kube-dns|coredns\"},\"git_version\",\"$1\",\"git_version\",\"(v[0-9]*.[0-9]*).*\"))) > 1\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeClientErrors\n      annotations:\n        description: Kubernetes API server client '{{ $labels.job }}/{{ $labels.instance }}' is experiencing {{ $value | humanizePercentage }} errors on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeclienterrors\n        summary: Kubernetes API server client is experiencing errors.\n      expr: |\n        (sum(rate(rest_client_requests_total{job=\"apiserver\",code=~\"5..\"}[5m])) by (cluster, instance, job, namespace)\n          /\n        sum(rate(rest_client_requests_total{job=\"apiserver\"}[5m])) by (cluster, instance, job, namespace))\n        > 0.01\n      for: 15m\n      labels:\n        severity: warning\n  - name: kube-apiserver-slos\n    rules:\n    - alert: KubeAPIErrorBudgetBurn\n      annotations:\n        description: The API server is burning too much error budget on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeapierrorbudgetburn\n        summary: The API server is burning too much error budget.\n      expr: |\n        sum by(cluster) (apiserver_request:burnrate1h) > (14.40 * 0.01000)\n        and on(cluster)\n        sum by(cluster) (apiserver_request:burnrate5m) > (14.40 * 0.01000)\n      for: 2m\n      labels:\n        long: 1h\n        severity: critical\n        short: 5m\n    - alert: KubeAPIErrorBudgetBurn\n      annotations:\n        description: The API server is burning too much error budget on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeapierrorbudgetburn\n        summary: The API server is burning too much error budget.\n      expr: |\n        sum by(cluster) (apiserver_request:burnrate6h) > (6.00 * 0.01000)\n        and on(cluster)\n        sum by(cluster) (apiserver_request:burnrate30m) > (6.00 * 0.01000)\n      for: 15m\n      labels:\n        long: 6h\n        severity: critical\n        short: 30m\n    - alert: KubeAPIErrorBudgetBurn\n      annotations:\n        description: The API server is burning too much error budget on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeapierrorbudgetburn\n        summary: The API server is burning too much error budget.\n      expr: |\n        sum by(cluster) (apiserver_request:burnrate1d) > (3.00 * 0.01000)\n        and on(cluster)\n        sum by(cluster) (apiserver_request:burnrate2h) > (3.00 * 0.01000)\n      for: 1h\n      labels:\n        long: 1d\n        severity: warning\n        short: 2h\n    - alert: KubeAPIErrorBudgetBurn\n      annotations:\n        description: The API server is burning too much error budget on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeapierrorbudgetburn\n        summary: The API server is burning too much error budget.\n      expr: |\n        sum by(cluster) (apiserver_request:burnrate3d) > (1.00 * 0.01000)\n        and on(cluster)\n        sum by(cluster) (apiserver_request:burnrate6h) > (1.00 * 0.01000)\n      for: 3h\n      labels:\n        long: 3d\n        severity: warning\n        short: 6h\n  - name: kubernetes-system-apiserver\n    rules:\n    - alert: KubeClientCertificateExpiration\n      annotations:\n        description: A client certificate used to authenticate to kubernetes apiserver is expiring in less than 7.0 days on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeclientcertificateexpiration\n        summary: Client certificate is about to expire.\n      expr: |\n        histogram_quantile(0.01, sum without (namespace, service, endpoint) (rate(apiserver_client_certificate_expiration_seconds_bucket{job=\"apiserver\"}[5m]))) < 604800\n        and\n        on(job, cluster, instance) apiserver_client_certificate_expiration_seconds_count{job=\"apiserver\"} > 0\n      for: 5m\n      labels:\n        severity: warning\n    - alert: KubeClientCertificateExpiration\n      annotations:\n        description: A client certificate used to authenticate to kubernetes apiserver is expiring in less than 24.0 hours on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeclientcertificateexpiration\n        summary: Client certificate is about to expire.\n      expr: |\n        histogram_quantile(0.01, sum without (namespace, service, endpoint) (rate(apiserver_client_certificate_expiration_seconds_bucket{job=\"apiserver\"}[5m]))) < 86400\n        and\n        on(job, cluster, instance) apiserver_client_certificate_expiration_seconds_count{job=\"apiserver\"} > 0\n      for: 5m\n      labels:\n        severity: critical\n    - alert: KubeAggregatedAPIErrors\n      annotations:\n        description: Kubernetes aggregated API {{ $labels.instance }}/{{ $labels.name }} has reported {{ $labels.reason }} errors on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeaggregatedapierrors\n        summary: Kubernetes aggregated API has reported errors.\n      expr: |\n        sum by(cluster, instance, name, reason)(increase(aggregator_unavailable_apiservice_total{job=\"apiserver\"}[1m])) > 0\n      for: 10m\n      labels:\n        severity: warning\n    - alert: KubeAggregatedAPIDown\n      annotations:\n        description: Kubernetes aggregated API {{ $labels.name }}/{{ $labels.namespace }} has been only {{ $value | humanize }}% available over the last 10m on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeaggregatedapidown\n        summary: Kubernetes aggregated API is down.\n      expr: |\n        (1 - max by(name, namespace, cluster)(avg_over_time(aggregator_unavailable_apiservice{job=\"apiserver\"}[10m]))) * 100 < 85\n      for: 5m\n      labels:\n        severity: warning\n    - alert: KubeAPIDown\n      annotations:\n        description: KubeAPI has disappeared from Prometheus target discovery.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeapidown\n        summary: Target disappeared from Prometheus target discovery.\n      expr: |\n        absent(up{job=\"apiserver\"} == 1)\n      for: 15m\n      labels:\n        severity: critical\n    - alert: KubeAPITerminatedRequests\n      annotations:\n        description: The kubernetes apiserver has terminated {{ $value | humanizePercentage }} of its incoming requests on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeapiterminatedrequests\n        summary: The kubernetes apiserver has terminated {{ $value | humanizePercentage }} of its incoming requests.\n      expr: |\n        sum by(cluster) (rate(apiserver_request_terminations_total{job=\"apiserver\"}[10m])) / ( sum by(cluster) (rate(apiserver_request_total{job=\"apiserver\"}[10m])) + sum by(cluster) (rate(apiserver_request_terminations_total{job=\"apiserver\"}[10m])) ) > 0.20\n      for: 5m\n      labels:\n        severity: warning\n  - name: kubernetes-system-kubelet\n    rules:\n    - alert: KubeNodeNotReady\n      annotations:\n        description: '{{ $labels.node }} has been unready for more than 15 minutes on cluster {{ $labels.cluster }}.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubenodenotready\n        summary: Node is not ready.\n      expr: |\n        kube_node_status_condition{job=\"kube-state-metrics\",condition=\"Ready\",status=\"true\"} == 0\n        and on (cluster, node)\n        kube_node_spec_unschedulable{job=\"kube-state-metrics\"} == 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeNodePressure\n      annotations:\n        description: '{{ $labels.node }} on cluster {{ $labels.cluster }} has active Condition {{ $labels.condition }}. This is caused by resource usage exceeding eviction thresholds.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubenodepressure\n        summary: Node has as active Condition.\n      expr: |\n        kube_node_status_condition{job=\"kube-state-metrics\",condition=~\"(MemoryPressure|DiskPressure|PIDPressure)\",status=\"true\"} == 1\n        and on (cluster, node)\n        kube_node_spec_unschedulable{job=\"kube-state-metrics\"} == 0\n      for: 10m\n      labels:\n        severity: info\n    - alert: KubeNodeUnreachable\n      annotations:\n        description: '{{ $labels.node }} is unreachable and some workloads may be rescheduled on cluster {{ $labels.cluster }}.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubenodeunreachable\n        summary: Node is unreachable.\n      expr: |\n        (kube_node_spec_taint{job=\"kube-state-metrics\",key=\"node.kubernetes.io/unreachable\",effect=\"NoSchedule\"} unless ignoring(key,value) kube_node_spec_taint{job=\"kube-state-metrics\",key=~\"ToBeDeletedByClusterAutoscaler|cloud.google.com/impending-node-termination|aws-node-termination-handler/spot-itn\"}) == 1\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeletTooManyPods\n      annotations:\n        description: Kubelet '{{ $labels.node }}' is running at {{ $value | humanizePercentage }} of its Pod capacity on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubelettoomanypods\n        summary: Kubelet is running at capacity.\n      expr: |\n        (\n          max by (cluster, instance) (\n            kubelet_running_pods{job=\"kubelet\", metrics_path=\"/metrics\"} > 1\n          )\n          * on (cluster, instance) group_left(node)\n          max by (cluster, instance, node) (\n            kubelet_node_name{job=\"kubelet\", metrics_path=\"/metrics\"}\n          )\n        )\n        / on (cluster, node) group_left()\n        max by (cluster, node) (\n          kube_node_status_capacity{job=\"kube-state-metrics\", resource=\"pods\"} != 1\n        ) > 0.95\n      for: 15m\n      labels:\n        severity: info\n    - alert: KubeNodeReadinessFlapping\n      annotations:\n        description: The readiness status of node {{ $labels.node }} has changed {{ $value }} times in the last 15 minutes on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubenodereadinessflapping\n        summary: Node readiness status is flapping.\n      expr: |\n        sum(changes(kube_node_status_condition{job=\"kube-state-metrics\",status=\"true\",condition=\"Ready\"}[15m])) by (cluster, node) > 2\n        and on (cluster, node)\n        kube_node_spec_unschedulable{job=\"kube-state-metrics\"} == 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeNodeEviction\n      annotations:\n        description: Node {{ $labels.node }} on {{ $labels.cluster }} is evicting Pods due to {{ $labels.eviction_signal }}.  Eviction occurs when eviction thresholds are crossed, typically caused by Pods exceeding RAM/ephemeral-storage limits.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubenodeeviction\n        summary: Node is evicting pods.\n      expr: |\n        sum(rate(kubelet_evictions{job=\"kubelet\", metrics_path=\"/metrics\"}[15m])) by(cluster, eviction_signal, instance)\n        * on (cluster, instance) group_left(node)\n        max by (cluster, instance, node) (\n          kubelet_node_name{job=\"kubelet\", metrics_path=\"/metrics\"}\n        )\n        > 0\n      for: 0s\n      labels:\n        severity: info\n    - alert: KubeletPlegDurationHigh\n      annotations:\n        description: The Kubelet Pod Lifecycle Event Generator has a 99th percentile duration of {{ $value }} seconds on node {{ $labels.node }} on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletplegdurationhigh\n        summary: Kubelet Pod Lifecycle Event Generator is taking too long to relist.\n      expr: |\n        node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile{quantile=\"0.99\"} >= 10\n      for: 5m\n      labels:\n        severity: warning\n    - alert: KubeletPodStartUpLatencyHigh\n      annotations:\n        description: Kubelet Pod startup 99th percentile latency is {{ $value }} seconds on node {{ $labels.node }} on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletpodstartuplatencyhigh\n        summary: Kubelet Pod startup latency is too high.\n      expr: |\n        histogram_quantile(0.99,\n          sum by (cluster, instance, le) (\n            topk by (cluster, instance, le, operation_type) (1,\n              rate(kubelet_pod_worker_duration_seconds_bucket{job=\"kubelet\", metrics_path=\"/metrics\"}[5m])\n            )\n          )\n        )\n        * on(cluster, instance) group_left(node)\n        topk by (cluster, instance, node) (1,\n          kubelet_node_name{job=\"kubelet\", metrics_path=\"/metrics\"}\n        )\n        > 60\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeletClientCertificateExpiration\n      annotations:\n        description: Client certificate for Kubelet on node {{ $labels.node }} expires in {{ $value | humanizeDuration }} on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletclientcertificateexpiration\n        summary: Kubelet client certificate is about to expire.\n      expr: |\n        kubelet_certificate_manager_client_ttl_seconds < 604800\n      labels:\n        severity: warning\n    - alert: KubeletClientCertificateExpiration\n      annotations:\n        description: Client certificate for Kubelet on node {{ $labels.node }} expires in {{ $value | humanizeDuration }} on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletclientcertificateexpiration\n        summary: Kubelet client certificate is about to expire.\n      expr: |\n        kubelet_certificate_manager_client_ttl_seconds < 86400\n      labels:\n        severity: critical\n    - alert: KubeletServerCertificateExpiration\n      annotations:\n        description: Server certificate for Kubelet on node {{ $labels.node }} expires in {{ $value | humanizeDuration }} on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletservercertificateexpiration\n        summary: Kubelet server certificate is about to expire.\n      expr: |\n        kubelet_certificate_manager_server_ttl_seconds < 604800\n      labels:\n        severity: warning\n    - alert: KubeletServerCertificateExpiration\n      annotations:\n        description: Server certificate for Kubelet on node {{ $labels.node }} expires in {{ $value | humanizeDuration }} on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletservercertificateexpiration\n        summary: Kubelet server certificate is about to expire.\n      expr: |\n        kubelet_certificate_manager_server_ttl_seconds < 86400\n      labels:\n        severity: critical\n    - alert: KubeletClientCertificateRenewalErrors\n      annotations:\n        description: Kubelet on node {{ $labels.node }} has failed to renew its client certificate ({{ $value | humanize }} errors in the last 5 minutes) on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletclientcertificaterenewalerrors\n        summary: Kubelet has failed to renew its client certificate.\n      expr: |\n        increase(kubelet_certificate_manager_client_expiration_renew_errors[5m]) > 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeletServerCertificateRenewalErrors\n      annotations:\n        description: Kubelet on node {{ $labels.node }} has failed to renew its server certificate ({{ $value | humanize }} errors in the last 5 minutes) on cluster {{ $labels.cluster }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletservercertificaterenewalerrors\n        summary: Kubelet has failed to renew its server certificate.\n      expr: |\n        increase(kubelet_server_expiration_renew_errors[5m]) > 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: KubeletDown\n      annotations:\n        description: Kubelet has disappeared from Prometheus target discovery.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeletdown\n        summary: Target disappeared from Prometheus target discovery.\n      expr: |\n        absent(up{job=\"kubelet\", metrics_path=\"/metrics\"} == 1)\n      for: 15m\n      labels:\n        severity: critical\n  - name: kubernetes-system-scheduler\n    rules:\n    - alert: KubeSchedulerDown\n      annotations:\n        description: KubeScheduler has disappeared from Prometheus target discovery.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubeschedulerdown\n        summary: Target disappeared from Prometheus target discovery.\n      expr: |\n        absent(up{job=\"kube-scheduler\"} == 1)\n      for: 15m\n      labels:\n        severity: critical\n  - name: kubernetes-system-controller-manager\n    rules:\n    - alert: KubeControllerManagerDown\n      annotations:\n        description: KubeControllerManager has disappeared from Prometheus target discovery.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubecontrollermanagerdown\n        summary: Target disappeared from Prometheus target discovery.\n      expr: |\n        absent(up{job=\"kube-controller-manager\"} == 1)\n      for: 15m\n      labels:\n        severity: critical\n  - interval: 3m\n    name: kube-apiserver-availability.rules\n    rules:\n    - expr: |\n        avg_over_time(code_verb:apiserver_request_total:increase1h[30d]) * 24 * 30\n      record: code_verb:apiserver_request_total:increase30d\n    - expr: |\n        sum by (cluster, code) (code_verb:apiserver_request_total:increase30d{verb=~\"LIST|GET\"})\n      labels:\n        verb: read\n      record: code:apiserver_request_total:increase30d\n    - expr: |\n        sum by (cluster, code) (code_verb:apiserver_request_total:increase30d{verb=~\"POST|PUT|PATCH|DELETE\"})\n      labels:\n        verb: write\n      record: code:apiserver_request_total:increase30d\n    - expr: |\n        sum by (cluster, verb, scope, le) (increase(apiserver_request_sli_duration_seconds_bucket[1h]))\n      record: cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase1h\n    - expr: |\n        sum by (cluster, verb, scope, le) (avg_over_time(cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase1h[30d]) * 24 * 30)\n      record: cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d\n    - expr: |\n        sum by (cluster, verb, scope) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase1h{le=\"+Inf\"})\n      record: cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase1h\n    - expr: |\n        sum by (cluster, verb, scope) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{le=\"+Inf\"})\n      record: cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase30d\n    - expr: |\n        1 - (\n          (\n            # write too slow\n            sum by (cluster) (cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase30d{verb=~\"POST|PUT|PATCH|DELETE\"})\n            -\n            sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~\"POST|PUT|PATCH|DELETE\",le=~\"1(\\\\.0)?\"} or vector(0))\n          ) +\n          (\n            # read too slow\n            sum by (cluster) (cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase30d{verb=~\"LIST|GET\"})\n            -\n            (\n              sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~\"LIST|GET\",scope=~\"resource|\",le=~\"1(\\\\.0)?\"} or vector(0))\n              +\n              sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~\"LIST|GET\",scope=\"namespace\",le=~\"5(\\\\.0)?\"} or vector(0))\n              +\n              sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~\"LIST|GET\",scope=\"cluster\",le=~\"30(\\\\.0)?\"} or vector(0))\n            )\n          ) +\n          # errors\n          sum by (cluster) (code:apiserver_request_total:increase30d{code=~\"5..\"} or vector(0))\n        )\n        /\n        sum by (cluster) (code:apiserver_request_total:increase30d)\n      labels:\n        verb: all\n      record: apiserver_request:availability30d\n    - expr: |\n        1 - (\n          sum by (cluster) (cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase30d{verb=~\"LIST|GET\"})\n          -\n          (\n            # too slow\n            sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~\"LIST|GET\",scope=~\"resource|\",le=~\"1(\\\\.0)?\"} or vector(0))\n            +\n            sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~\"LIST|GET\",scope=\"namespace\",le=~\"5(\\\\.0)?\"} or vector(0))\n            +\n            sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~\"LIST|GET\",scope=\"cluster\",le=~\"30(\\\\.0)?\"} or vector(0))\n          )\n          +\n          # errors\n          sum by (cluster) (code:apiserver_request_total:increase30d{verb=\"read\",code=~\"5..\"} or vector(0))\n        )\n        /\n        sum by (cluster) (code:apiserver_request_total:increase30d{verb=\"read\"})\n      labels:\n        verb: read\n      record: apiserver_request:availability30d\n    - expr: |\n        1 - (\n          (\n            # too slow\n            sum by (cluster) (cluster_verb_scope:apiserver_request_sli_duration_seconds_count:increase30d{verb=~\"POST|PUT|PATCH|DELETE\"})\n            -\n            sum by (cluster) (cluster_verb_scope_le:apiserver_request_sli_duration_seconds_bucket:increase30d{verb=~\"POST|PUT|PATCH|DELETE\",le=~\"1(\\\\.0)?\"} or vector(0))\n          )\n          +\n          # errors\n          sum by (cluster) (code:apiserver_request_total:increase30d{verb=\"write\",code=~\"5..\"} or vector(0))\n        )\n        /\n        sum by (cluster) (code:apiserver_request_total:increase30d{verb=\"write\"})\n      labels:\n        verb: write\n      record: apiserver_request:availability30d\n    - expr: |\n        sum by (cluster,code,resource) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\"}[5m]))\n      labels:\n        verb: read\n      record: code_resource:apiserver_request_total:rate5m\n    - expr: |\n        sum by (cluster,code,resource) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\"}[5m]))\n      labels:\n        verb: write\n      record: code_resource:apiserver_request_total:rate5m\n    - expr: |\n        sum by (cluster, code, verb) (increase(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET|POST|PUT|PATCH|DELETE\",code=~\"2..\"}[1h]))\n      record: code_verb:apiserver_request_total:increase1h\n    - expr: |\n        sum by (cluster, code, verb) (increase(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET|POST|PUT|PATCH|DELETE\",code=~\"3..\"}[1h]))\n      record: code_verb:apiserver_request_total:increase1h\n    - expr: |\n        sum by (cluster, code, verb) (increase(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET|POST|PUT|PATCH|DELETE\",code=~\"4..\"}[1h]))\n      record: code_verb:apiserver_request_total:increase1h\n    - expr: |\n        sum by (cluster, code, verb) (increase(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET|POST|PUT|PATCH|DELETE\",code=~\"5..\"}[1h]))\n      record: code_verb:apiserver_request_total:increase1h\n  - name: kube-apiserver-burnrate.rules\n    rules:\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\"}[1d]))\n            -\n            (\n              (\n                sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=~\"resource|\",le=~\"1(\\\\.0)?\"}[1d]))\n                or\n                vector(0)\n              )\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"namespace\",le=~\"5(\\\\.0)?\"}[1d]))\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"cluster\",le=~\"30(\\\\.0)?\"}[1d]))\n            )\n          )\n          +\n          # errors\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\",code=~\"5..\"}[1d]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\"}[1d]))\n      labels:\n        verb: read\n      record: apiserver_request:burnrate1d\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\"}[1h]))\n            -\n            (\n              (\n                sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=~\"resource|\",le=~\"1(\\\\.0)?\"}[1h]))\n                or\n                vector(0)\n              )\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"namespace\",le=~\"5(\\\\.0)?\"}[1h]))\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"cluster\",le=~\"30(\\\\.0)?\"}[1h]))\n            )\n          )\n          +\n          # errors\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\",code=~\"5..\"}[1h]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\"}[1h]))\n      labels:\n        verb: read\n      record: apiserver_request:burnrate1h\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\"}[2h]))\n            -\n            (\n              (\n                sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=~\"resource|\",le=~\"1(\\\\.0)?\"}[2h]))\n                or\n                vector(0)\n              )\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"namespace\",le=~\"5(\\\\.0)?\"}[2h]))\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"cluster\",le=~\"30(\\\\.0)?\"}[2h]))\n            )\n          )\n          +\n          # errors\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\",code=~\"5..\"}[2h]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\"}[2h]))\n      labels:\n        verb: read\n      record: apiserver_request:burnrate2h\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\"}[30m]))\n            -\n            (\n              (\n                sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=~\"resource|\",le=~\"1(\\\\.0)?\"}[30m]))\n                or\n                vector(0)\n              )\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"namespace\",le=~\"5(\\\\.0)?\"}[30m]))\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"cluster\",le=~\"30(\\\\.0)?\"}[30m]))\n            )\n          )\n          +\n          # errors\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\",code=~\"5..\"}[30m]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\"}[30m]))\n      labels:\n        verb: read\n      record: apiserver_request:burnrate30m\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\"}[3d]))\n            -\n            (\n              (\n                sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=~\"resource|\",le=~\"1(\\\\.0)?\"}[3d]))\n                or\n                vector(0)\n              )\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"namespace\",le=~\"5(\\\\.0)?\"}[3d]))\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"cluster\",le=~\"30(\\\\.0)?\"}[3d]))\n            )\n          )\n          +\n          # errors\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\",code=~\"5..\"}[3d]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\"}[3d]))\n      labels:\n        verb: read\n      record: apiserver_request:burnrate3d\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\"}[5m]))\n            -\n            (\n              (\n                sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=~\"resource|\",le=~\"1(\\\\.0)?\"}[5m]))\n                or\n                vector(0)\n              )\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"namespace\",le=~\"5(\\\\.0)?\"}[5m]))\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"cluster\",le=~\"30(\\\\.0)?\"}[5m]))\n            )\n          )\n          +\n          # errors\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\",code=~\"5..\"}[5m]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\"}[5m]))\n      labels:\n        verb: read\n      record: apiserver_request:burnrate5m\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\"}[6h]))\n            -\n            (\n              (\n                sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=~\"resource|\",le=~\"1(\\\\.0)?\"}[6h]))\n                or\n                vector(0)\n              )\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"namespace\",le=~\"5(\\\\.0)?\"}[6h]))\n              +\n              sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\",scope=\"cluster\",le=~\"30(\\\\.0)?\"}[6h]))\n            )\n          )\n          +\n          # errors\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\",code=~\"5..\"}[6h]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"LIST|GET\"}[6h]))\n      labels:\n        verb: read\n      record: apiserver_request:burnrate6h\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\"}[1d]))\n            -\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\",le=~\"1(\\\\.0)?\"}[1d]))\n          )\n          +\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",code=~\"5..\"}[1d]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\"}[1d]))\n      labels:\n        verb: write\n      record: apiserver_request:burnrate1d\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\"}[1h]))\n            -\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\",le=~\"1(\\\\.0)?\"}[1h]))\n          )\n          +\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",code=~\"5..\"}[1h]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\"}[1h]))\n      labels:\n        verb: write\n      record: apiserver_request:burnrate1h\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\"}[2h]))\n            -\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\",le=~\"1(\\\\.0)?\"}[2h]))\n          )\n          +\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",code=~\"5..\"}[2h]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\"}[2h]))\n      labels:\n        verb: write\n      record: apiserver_request:burnrate2h\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\"}[30m]))\n            -\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\",le=~\"1(\\\\.0)?\"}[30m]))\n          )\n          +\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",code=~\"5..\"}[30m]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\"}[30m]))\n      labels:\n        verb: write\n      record: apiserver_request:burnrate30m\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\"}[3d]))\n            -\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\",le=~\"1(\\\\.0)?\"}[3d]))\n          )\n          +\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",code=~\"5..\"}[3d]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\"}[3d]))\n      labels:\n        verb: write\n      record: apiserver_request:burnrate3d\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\"}[5m]))\n            -\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\",le=~\"1(\\\\.0)?\"}[5m]))\n          )\n          +\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",code=~\"5..\"}[5m]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\"}[5m]))\n      labels:\n        verb: write\n      record: apiserver_request:burnrate5m\n    - expr: |\n        (\n          (\n            # too slow\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_count{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\"}[6h]))\n            -\n            sum by (cluster) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\",le=~\"1(\\\\.0)?\"}[6h]))\n          )\n          +\n          sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",code=~\"5..\"}[6h]))\n        )\n        /\n        sum by (cluster) (rate(apiserver_request_total{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\"}[6h]))\n      labels:\n        verb: write\n      record: apiserver_request:burnrate6h\n  - name: kube-apiserver-histogram.rules\n    rules:\n    - expr: |\n        histogram_quantile(0.99, sum by (cluster, le, resource) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"LIST|GET\",subresource!~\"proxy|attach|log|exec|portforward\"}[5m]))) > 0\n      labels:\n        quantile: \"0.99\"\n        verb: read\n      record: cluster_quantile:apiserver_request_sli_duration_seconds:histogram_quantile\n    - expr: |\n        histogram_quantile(0.99, sum by (cluster, le, resource) (rate(apiserver_request_sli_duration_seconds_bucket{job=\"apiserver\",verb=~\"POST|PUT|PATCH|DELETE\",subresource!~\"proxy|attach|log|exec|portforward\"}[5m]))) > 0\n      labels:\n        quantile: \"0.99\"\n        verb: write\n      record: cluster_quantile:apiserver_request_sli_duration_seconds:histogram_quantile\n  - name: k8s.rules.container_cpu_usage_seconds_total\n    rules:\n    - expr: |\n        sum by (cluster, namespace, pod, container) (\n          rate(container_cpu_usage_seconds_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", image!=\"\"}[5m])\n        ) * on (cluster, namespace, pod) group_left(node) topk by (cluster, namespace, pod) (\n          1, max by(cluster, namespace, pod, node) (kube_pod_info{node!=\"\"})\n        )\n      record: node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate5m\n    - expr: |\n        sum by (cluster, namespace, pod, container) (\n          irate(container_cpu_usage_seconds_total{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", image!=\"\"}[5m])\n        ) * on (cluster, namespace, pod) group_left(node) topk by (cluster, namespace, pod) (\n          1, max by(cluster, namespace, pod, node) (kube_pod_info{node!=\"\"})\n        )\n      record: node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate\n  - name: k8s.rules.container_memory_working_set_bytes\n    rules:\n    - expr: |\n        container_memory_working_set_bytes{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", image!=\"\"}\n        * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1,\n          max by(cluster, namespace, pod, node) (kube_pod_info{node!=\"\"})\n        )\n      record: node_namespace_pod_container:container_memory_working_set_bytes\n  - name: k8s.rules.container_memory_rss\n    rules:\n    - expr: |\n        container_memory_rss{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", image!=\"\"}\n        * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1,\n          max by(cluster, namespace, pod, node) (kube_pod_info{node!=\"\"})\n        )\n      record: node_namespace_pod_container:container_memory_rss\n  - name: k8s.rules.container_memory_cache\n    rules:\n    - expr: |\n        container_memory_cache{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", image!=\"\"}\n        * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1,\n          max by(cluster, namespace, pod, node) (kube_pod_info{node!=\"\"})\n        )\n      record: node_namespace_pod_container:container_memory_cache\n  - name: k8s.rules.container_memory_swap\n    rules:\n    - expr: |\n        container_memory_swap{job=\"kubelet\", metrics_path=\"/metrics/cadvisor\", image!=\"\"}\n        * on (cluster, namespace, pod) group_left(node) topk by(cluster, namespace, pod) (1,\n          max by(cluster, namespace, pod, node) (kube_pod_info{node!=\"\"})\n        )\n      record: node_namespace_pod_container:container_memory_swap\n  - name: k8s.rules.container_memory_requests\n    rules:\n    - expr: |\n        kube_pod_container_resource_requests{resource=\"memory\",job=\"kube-state-metrics\"}  * on (namespace, pod, cluster)\n        group_left() max by (namespace, pod, cluster) (\n          (kube_pod_status_phase{phase=~\"Pending|Running\"} == 1)\n        )\n      record: cluster:namespace:pod_memory:active:kube_pod_container_resource_requests\n    - expr: |\n        sum by (namespace, cluster) (\n            sum by (namespace, pod, cluster) (\n                max by (namespace, pod, container, cluster) (\n                  kube_pod_container_resource_requests{resource=\"memory\",job=\"kube-state-metrics\"}\n                ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) (\n                  kube_pod_status_phase{phase=~\"Pending|Running\"} == 1\n                )\n            )\n        )\n      record: namespace_memory:kube_pod_container_resource_requests:sum\n  - name: k8s.rules.container_cpu_requests\n    rules:\n    - expr: |\n        kube_pod_container_resource_requests{resource=\"cpu\",job=\"kube-state-metrics\"}  * on (namespace, pod, cluster)\n        group_left() max by (namespace, pod, cluster) (\n          (kube_pod_status_phase{phase=~\"Pending|Running\"} == 1)\n        )\n      record: cluster:namespace:pod_cpu:active:kube_pod_container_resource_requests\n    - expr: |\n        sum by (namespace, cluster) (\n            sum by (namespace, pod, cluster) (\n                max by (namespace, pod, container, cluster) (\n                  kube_pod_container_resource_requests{resource=\"cpu\",job=\"kube-state-metrics\"}\n                ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) (\n                  kube_pod_status_phase{phase=~\"Pending|Running\"} == 1\n                )\n            )\n        )\n      record: namespace_cpu:kube_pod_container_resource_requests:sum\n  - name: k8s.rules.container_memory_limits\n    rules:\n    - expr: |\n        kube_pod_container_resource_limits{resource=\"memory\",job=\"kube-state-metrics\"}  * on (namespace, pod, cluster)\n        group_left() max by (namespace, pod, cluster) (\n          (kube_pod_status_phase{phase=~\"Pending|Running\"} == 1)\n        )\n      record: cluster:namespace:pod_memory:active:kube_pod_container_resource_limits\n    - expr: |\n        sum by (namespace, cluster) (\n            sum by (namespace, pod, cluster) (\n                max by (namespace, pod, container, cluster) (\n                  kube_pod_container_resource_limits{resource=\"memory\",job=\"kube-state-metrics\"}\n                ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) (\n                  kube_pod_status_phase{phase=~\"Pending|Running\"} == 1\n                )\n            )\n        )\n      record: namespace_memory:kube_pod_container_resource_limits:sum\n  - name: k8s.rules.container_cpu_limits\n    rules:\n    - expr: |\n        kube_pod_container_resource_limits{resource=\"cpu\",job=\"kube-state-metrics\"}  * on (namespace, pod, cluster)\n        group_left() max by (namespace, pod, cluster) (\n          (kube_pod_status_phase{phase=~\"Pending|Running\"} == 1)\n        )\n      record: cluster:namespace:pod_cpu:active:kube_pod_container_resource_limits\n    - expr: |\n        sum by (namespace, cluster) (\n            sum by (namespace, pod, cluster) (\n                max by (namespace, pod, container, cluster) (\n                  kube_pod_container_resource_limits{resource=\"cpu\",job=\"kube-state-metrics\"}\n                ) * on(namespace, pod, cluster) group_left() max by (namespace, pod, cluster) (\n                  kube_pod_status_phase{phase=~\"Pending|Running\"} == 1\n                )\n            )\n        )\n      record: namespace_cpu:kube_pod_container_resource_limits:sum\n  - name: k8s.rules.pod_owner\n    rules:\n    - expr: |\n        max by (cluster, namespace, workload, pod) (\n          label_replace(\n            label_replace(\n              kube_pod_owner{job=\"kube-state-metrics\", owner_kind=\"ReplicaSet\"},\n              \"replicaset\", \"$1\", \"owner_name\", \"(.*)\"\n            ) * on (cluster, replicaset, namespace) group_left(owner_name) topk by(cluster, replicaset, namespace) (\n              1, max by (cluster, replicaset, namespace, owner_name) (\n                kube_replicaset_owner{job=\"kube-state-metrics\", owner_kind=\"\"}\n              )\n            ),\n            \"workload\", \"$1\", \"replicaset\", \"(.*)\"\n          )\n        )\n      labels:\n        workload_type: replicaset\n      record: namespace_workload_pod:kube_pod_owner:relabel\n    - expr: |\n        max by (cluster, namespace, workload, pod) (\n          label_replace(\n            label_replace(\n              kube_pod_owner{job=\"kube-state-metrics\", owner_kind=\"ReplicaSet\"},\n              \"replicaset\", \"$1\", \"owner_name\", \"(.*)\"\n            ) * on(replicaset, namespace, cluster) group_left(owner_name) topk by(cluster, replicaset, namespace) (\n              1, max by (cluster, replicaset, namespace, owner_name) (\n                kube_replicaset_owner{job=\"kube-state-metrics\", owner_kind=\"Deployment\"}\n              )\n            ),\n            \"workload\", \"$1\", \"owner_name\", \"(.*)\"\n          )\n        )\n      labels:\n        workload_type: deployment\n      record: namespace_workload_pod:kube_pod_owner:relabel\n    - expr: |\n        max by (cluster, namespace, workload, pod) (\n          label_replace(\n            kube_pod_owner{job=\"kube-state-metrics\", owner_kind=\"DaemonSet\"},\n            \"workload\", \"$1\", \"owner_name\", \"(.*)\"\n          )\n        )\n      labels:\n        workload_type: daemonset\n      record: namespace_workload_pod:kube_pod_owner:relabel\n    - expr: |\n        max by (cluster, namespace, workload, pod) (\n          label_replace(\n            kube_pod_owner{job=\"kube-state-metrics\", owner_kind=\"StatefulSet\"},\n          \"workload\", \"$1\", \"owner_name\", \"(.*)\")\n        )\n      labels:\n        workload_type: statefulset\n      record: namespace_workload_pod:kube_pod_owner:relabel\n    - expr: |\n        group by (cluster, namespace, workload, pod) (\n          label_join(\n            group by (cluster, namespace, job_name, pod, owner_name) (\n              label_join(\n                kube_pod_owner{job=\"kube-state-metrics\", owner_kind=\"Job\"}\n              , \"job_name\", \"\", \"owner_name\")\n            )\n            * on (cluster, namespace, job_name) group_left()\n            group by (cluster, namespace, job_name) (\n              kube_job_owner{job=\"kube-state-metrics\", owner_kind=~\"Pod|\"}\n            )\n          , \"workload\", \"\", \"owner_name\")\n        )\n      labels:\n        workload_type: job\n      record: namespace_workload_pod:kube_pod_owner:relabel\n    - expr: |\n        max by (cluster, namespace, workload, pod) (\n          label_replace(\n            kube_pod_owner{job=\"kube-state-metrics\", owner_kind=\"\", owner_name=\"\"},\n          \"workload\", \"$1\", \"pod\", \"(.+)\")\n        )\n      labels:\n        workload_type: barepod\n      record: namespace_workload_pod:kube_pod_owner:relabel\n    - expr: |\n        max by (cluster, namespace, workload, pod) (\n          label_replace(\n            kube_pod_owner{job=\"kube-state-metrics\", owner_kind=\"Node\"},\n          \"workload\", \"$1\", \"pod\", \"(.+)\")\n        )\n      labels:\n        workload_type: staticpod\n      record: namespace_workload_pod:kube_pod_owner:relabel\n    - expr: |\n        group by (cluster, namespace, workload, workload_type, pod) (\n          label_join(\n            label_join(\n              group by (cluster, namespace, job_name, pod) (\n                label_join(\n                  kube_pod_owner{job=\"kube-state-metrics\", owner_kind=\"Job\"}\n                , \"job_name\", \"\", \"owner_name\")\n              )\n              * on (cluster, namespace, job_name) group_left(owner_kind, owner_name)\n              group by (cluster, namespace, job_name, owner_kind, owner_name) (\n                kube_job_owner{job=\"kube-state-metrics\", owner_kind!=\"Pod\", owner_kind!=\"\"}\n              )\n            , \"workload\", \"\", \"owner_name\")\n          , \"workload_type\", \"\", \"owner_kind\")\n\n          OR\n\n          label_replace(\n            label_replace(\n              label_replace(\n                kube_pod_owner{job=\"kube-state-metrics\", owner_kind=\"ReplicaSet\"}\n                , \"replicaset\", \"$1\", \"owner_name\", \"(.+)\"\n              )\n              * on(cluster, namespace, replicaset) group_left(owner_kind, owner_name)\n              group by (cluster, namespace, replicaset, owner_kind, owner_name) (\n                kube_replicaset_owner{job=\"kube-state-metrics\", owner_kind!=\"Deployment\", owner_kind!=\"\"}\n              )\n            , \"workload\", \"$1\", \"owner_name\", \"(.+)\")\n            OR\n            label_replace(\n              group by (cluster, namespace, pod, owner_name, owner_kind) (\n                kube_pod_owner{job=\"kube-state-metrics\", owner_kind!=\"ReplicaSet\", owner_kind!=\"DaemonSet\", owner_kind!=\"StatefulSet\", owner_kind!=\"Job\", owner_kind!=\"Node\", owner_kind!=\"\"}\n              )\n              , \"workload\", \"$1\", \"owner_name\", \"(.+)\"\n            )\n          , \"workload_type\", \"$1\", \"owner_kind\", \"(.+)\")\n        )\n      record: namespace_workload_pod:kube_pod_owner:relabel\n  - name: kube-scheduler.rules\n    rules:\n    - expr: |\n        histogram_quantile(0.99, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job=\"kube-scheduler\"}[5m])) without(instance, pod))\n      labels:\n        quantile: \"0.99\"\n      record: cluster_quantile:scheduler_e2e_scheduling_duration_seconds:histogram_quantile\n    - expr: |\n        histogram_quantile(0.99, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{job=\"kube-scheduler\"}[5m])) without(instance, pod))\n      labels:\n        quantile: \"0.99\"\n      record: cluster_quantile:scheduler_scheduling_algorithm_duration_seconds:histogram_quantile\n    - expr: |\n        histogram_quantile(0.99, sum(rate(scheduler_binding_duration_seconds_bucket{job=\"kube-scheduler\"}[5m])) without(instance, pod))\n      labels:\n        quantile: \"0.99\"\n      record: cluster_quantile:scheduler_binding_duration_seconds:histogram_quantile\n    - expr: |\n        histogram_quantile(0.9, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job=\"kube-scheduler\"}[5m])) without(instance, pod))\n      labels:\n        quantile: \"0.9\"\n      record: cluster_quantile:scheduler_e2e_scheduling_duration_seconds:histogram_quantile\n    - expr: |\n        histogram_quantile(0.9, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{job=\"kube-scheduler\"}[5m])) without(instance, pod))\n      labels:\n        quantile: \"0.9\"\n      record: cluster_quantile:scheduler_scheduling_algorithm_duration_seconds:histogram_quantile\n    - expr: |\n        histogram_quantile(0.9, sum(rate(scheduler_binding_duration_seconds_bucket{job=\"kube-scheduler\"}[5m])) without(instance, pod))\n      labels:\n        quantile: \"0.9\"\n      record: cluster_quantile:scheduler_binding_duration_seconds:histogram_quantile\n    - expr: |\n        histogram_quantile(0.5, sum(rate(scheduler_e2e_scheduling_duration_seconds_bucket{job=\"kube-scheduler\"}[5m])) without(instance, pod))\n      labels:\n        quantile: \"0.5\"\n      record: cluster_quantile:scheduler_e2e_scheduling_duration_seconds:histogram_quantile\n    - expr: |\n        histogram_quantile(0.5, sum(rate(scheduler_scheduling_algorithm_duration_seconds_bucket{job=\"kube-scheduler\"}[5m])) without(instance, pod))\n      labels:\n        quantile: \"0.5\"\n      record: cluster_quantile:scheduler_scheduling_algorithm_duration_seconds:histogram_quantile\n    - expr: |\n        histogram_quantile(0.5, sum(rate(scheduler_binding_duration_seconds_bucket{job=\"kube-scheduler\"}[5m])) without(instance, pod))\n      labels:\n        quantile: \"0.5\"\n      record: cluster_quantile:scheduler_binding_duration_seconds:histogram_quantile\n  - name: node.rules\n    rules:\n    - expr: |\n        topk by(cluster, namespace, pod) (1,\n          max by (cluster, node, namespace, pod) (\n            label_replace(kube_pod_info{job=\"kube-state-metrics\",node!=\"\"}, \"pod\", \"$1\", \"pod\", \"(.*)\")\n        ))\n      record: 'node_namespace_pod:kube_pod_info:'\n    - expr: |\n        count by (cluster, node) (\n          node_cpu_seconds_total{mode=\"idle\",job=\"node-exporter\"}\n          * on (cluster, namespace, pod) group_left(node)\n          topk by(cluster, namespace, pod) (1, node_namespace_pod:kube_pod_info:)\n        )\n      record: node:node_num_cpu:sum\n    - expr: |\n        sum(\n          node_memory_MemAvailable_bytes{job=\"node-exporter\"} or\n          (\n            node_memory_Buffers_bytes{job=\"node-exporter\"} +\n            node_memory_Cached_bytes{job=\"node-exporter\"} +\n            node_memory_MemFree_bytes{job=\"node-exporter\"} +\n            node_memory_Slab_bytes{job=\"node-exporter\"}\n          )\n        ) by (cluster)\n      record: :node_memory_MemAvailable_bytes:sum\n    - expr: |\n        avg by (cluster, node) (\n          sum without (mode) (\n            rate(node_cpu_seconds_total{mode!=\"idle\",mode!=\"iowait\",mode!=\"steal\",job=\"node-exporter\"}[5m])\n          )\n        )\n      record: node:node_cpu_utilization:ratio_rate5m\n    - expr: |\n        avg by (cluster) (\n          node:node_cpu_utilization:ratio_rate5m\n        )\n      record: cluster:node_cpu:ratio_rate5m\n  - name: kubelet.rules\n    rules:\n    - expr: |\n        histogram_quantile(\n          0.99,\n          sum(rate(kubelet_pleg_relist_duration_seconds_bucket{job=\"kubelet\", metrics_path=\"/metrics\"}[5m])) by (cluster, instance, le)\n          * on(cluster, instance) group_left (node)\n          max by (cluster, instance, node) (kubelet_node_name{job=\"kubelet\", metrics_path=\"/metrics\"})\n        )\n      labels:\n        quantile: \"0.99\"\n      record: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile\n    - expr: |\n        histogram_quantile(\n          0.9,\n          sum(rate(kubelet_pleg_relist_duration_seconds_bucket{job=\"kubelet\", metrics_path=\"/metrics\"}[5m])) by (cluster, instance, le)\n          * on(cluster, instance) group_left (node)\n          max by (cluster, instance, node) (kubelet_node_name{job=\"kubelet\", metrics_path=\"/metrics\"})\n        )\n      labels:\n        quantile: \"0.9\"\n      record: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile\n    - expr: |\n        histogram_quantile(\n          0.5,\n          sum(rate(kubelet_pleg_relist_duration_seconds_bucket{job=\"kubelet\", metrics_path=\"/metrics\"}[5m])) by (cluster, instance, le)\n          * on(cluster, instance) group_left (node)\n          max by (cluster, instance, node) (kubelet_node_name{job=\"kubelet\", metrics_path=\"/metrics\"})\n        )\n      labels:\n        quantile: \"0.5\"\n      record: node_quantile:kubelet_pleg_relist_duration_seconds:histogram_quantile\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubernetesControlPlane-serviceMonitorApiserver.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  labels:\n    app.kubernetes.io/component: kubernetes\n    app.kubernetes.io/name: apiserver\n    app.kubernetes.io/part-of: kube-prometheus\n  name: kube-apiserver\n  namespace: monitoring\nspec:\n  endpoints:\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    interval: 30s\n    metricRelabelings:\n    - action: drop\n      regex: kubelet_(pod_worker_latency_microseconds|pod_start_latency_microseconds|cgroup_manager_latency_microseconds|pod_worker_start_latency_microseconds|pleg_relist_latency_microseconds|pleg_relist_interval_microseconds|runtime_operations|runtime_operations_latency_microseconds|runtime_operations_errors|eviction_stats_age_microseconds|device_plugin_registration_count|device_plugin_alloc_latency_microseconds|network_plugin_operations_latency_microseconds)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: scheduler_(e2e_scheduling_latency_microseconds|scheduling_algorithm_predicate_evaluation|scheduling_algorithm_priority_evaluation|scheduling_algorithm_preemption_evaluation|scheduling_algorithm_latency_microseconds|binding_latency_microseconds|scheduling_latency_seconds)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: apiserver_(request_count|request_latencies|request_latencies_summary|dropped_requests|storage_data_key_generation_latencies_microseconds|storage_transformation_failures_total|storage_transformation_latencies_microseconds|proxy_tunnel_sync_latency_secs|longrunning_gauge|registered_watchers|storage_db_total_size_in_bytes|flowcontrol_request_concurrency_limit|flowcontrol_request_concurrency_in_use)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: kubelet_docker_(operations|operations_latency_microseconds|operations_errors|operations_timeout)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: reflector_(items_per_list|items_per_watch|list_duration_seconds|lists_total|short_watches_total|watch_duration_seconds|watches_total)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: etcd_(helper_cache_hit_count|helper_cache_miss_count|helper_cache_entry_count|object_counts|request_cache_get_latencies_summary|request_cache_add_latencies_summary|request_latencies_summary)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: transformation_(transformation_latencies_microseconds|failures_total)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: (admission_quota_controller_adds|admission_quota_controller_depth|admission_quota_controller_longest_running_processor_microseconds|admission_quota_controller_queue_latency|admission_quota_controller_unfinished_work_seconds|admission_quota_controller_work_duration|APIServiceOpenAPIAggregationControllerQueue1_adds|APIServiceOpenAPIAggregationControllerQueue1_depth|APIServiceOpenAPIAggregationControllerQueue1_longest_running_processor_microseconds|APIServiceOpenAPIAggregationControllerQueue1_queue_latency|APIServiceOpenAPIAggregationControllerQueue1_retries|APIServiceOpenAPIAggregationControllerQueue1_unfinished_work_seconds|APIServiceOpenAPIAggregationControllerQueue1_work_duration|APIServiceRegistrationController_adds|APIServiceRegistrationController_depth|APIServiceRegistrationController_longest_running_processor_microseconds|APIServiceRegistrationController_queue_latency|APIServiceRegistrationController_retries|APIServiceRegistrationController_unfinished_work_seconds|APIServiceRegistrationController_work_duration|autoregister_adds|autoregister_depth|autoregister_longest_running_processor_microseconds|autoregister_queue_latency|autoregister_retries|autoregister_unfinished_work_seconds|autoregister_work_duration|AvailableConditionController_adds|AvailableConditionController_depth|AvailableConditionController_longest_running_processor_microseconds|AvailableConditionController_queue_latency|AvailableConditionController_retries|AvailableConditionController_unfinished_work_seconds|AvailableConditionController_work_duration|crd_autoregistration_controller_adds|crd_autoregistration_controller_depth|crd_autoregistration_controller_longest_running_processor_microseconds|crd_autoregistration_controller_queue_latency|crd_autoregistration_controller_retries|crd_autoregistration_controller_unfinished_work_seconds|crd_autoregistration_controller_work_duration|crdEstablishing_adds|crdEstablishing_depth|crdEstablishing_longest_running_processor_microseconds|crdEstablishing_queue_latency|crdEstablishing_retries|crdEstablishing_unfinished_work_seconds|crdEstablishing_work_duration|crd_finalizer_adds|crd_finalizer_depth|crd_finalizer_longest_running_processor_microseconds|crd_finalizer_queue_latency|crd_finalizer_retries|crd_finalizer_unfinished_work_seconds|crd_finalizer_work_duration|crd_naming_condition_controller_adds|crd_naming_condition_controller_depth|crd_naming_condition_controller_longest_running_processor_microseconds|crd_naming_condition_controller_queue_latency|crd_naming_condition_controller_retries|crd_naming_condition_controller_unfinished_work_seconds|crd_naming_condition_controller_work_duration|crd_openapi_controller_adds|crd_openapi_controller_depth|crd_openapi_controller_longest_running_processor_microseconds|crd_openapi_controller_queue_latency|crd_openapi_controller_retries|crd_openapi_controller_unfinished_work_seconds|crd_openapi_controller_work_duration|DiscoveryController_adds|DiscoveryController_depth|DiscoveryController_longest_running_processor_microseconds|DiscoveryController_queue_latency|DiscoveryController_retries|DiscoveryController_unfinished_work_seconds|DiscoveryController_work_duration|kubeproxy_sync_proxy_rules_latency_microseconds|non_structural_schema_condition_controller_adds|non_structural_schema_condition_controller_depth|non_structural_schema_condition_controller_longest_running_processor_microseconds|non_structural_schema_condition_controller_queue_latency|non_structural_schema_condition_controller_retries|non_structural_schema_condition_controller_unfinished_work_seconds|non_structural_schema_condition_controller_work_duration|rest_client_request_latency_seconds|storage_operation_errors_total|storage_operation_status_count)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: etcd_(debugging|disk|server).*\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: apiserver_admission_controller_admission_latencies_seconds_.*\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: apiserver_admission_step_admission_latencies_seconds_.*\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: (apiserver_request|apiserver_request_sli|etcd_request)_duration_seconds_bucket;(0.15|0.25|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2.5|3|3.5|4.5|6|7|8|9|15|25|30|50)\n      sourceLabels:\n      - __name__\n      - le\n    - action: drop\n      regex: apiserver_request_body_size_bytes_bucket;(150000|350000|550000|650000|850000|950000|(1\\.15|1\\.35|1\\.55|1\\.65|1\\.85|1\\.95|2\\.15|2\\.35|2\\.55|2\\.65|2\\.85|2\\.95)e\\+06)\n      sourceLabels:\n      - __name__\n      - le\n    port: https\n    scheme: https\n    tlsConfig:\n      caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt\n      serverName: kubernetes\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    interval: 5s\n    metricRelabelings:\n    - action: drop\n      regex: process_start_time_seconds\n      sourceLabels:\n      - __name__\n    path: /metrics/slis\n    port: https\n    scheme: https\n    tlsConfig:\n      caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt\n      serverName: kubernetes\n  jobLabel: component\n  namespaceSelector:\n    matchNames:\n    - default\n  selector:\n    matchLabels:\n      component: apiserver\n      provider: kubernetes\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubernetesControlPlane-serviceMonitorCoreDNS.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  labels:\n    app.kubernetes.io/component: kubernetes\n    app.kubernetes.io/name: coredns\n    app.kubernetes.io/part-of: kube-prometheus\n  name: coredns\n  namespace: monitoring\nspec:\n  endpoints:\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    interval: 15s\n    metricRelabelings:\n    - action: drop\n      regex: coredns_cache_misses_total\n      sourceLabels:\n      - __name__\n    port: metrics\n  jobLabel: app.kubernetes.io/name\n  namespaceSelector:\n    matchNames:\n    - kube-system\n  selector:\n    matchLabels:\n      k8s-app: kube-dns\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubernetesControlPlane-serviceMonitorKubeControllerManager.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  labels:\n    app.kubernetes.io/component: kubernetes\n    app.kubernetes.io/name: kube-controller-manager\n    app.kubernetes.io/part-of: kube-prometheus\n  name: kube-controller-manager\n  namespace: monitoring\nspec:\n  endpoints:\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    interval: 30s\n    metricRelabelings:\n    - action: drop\n      regex: kubelet_(pod_worker_latency_microseconds|pod_start_latency_microseconds|cgroup_manager_latency_microseconds|pod_worker_start_latency_microseconds|pleg_relist_latency_microseconds|pleg_relist_interval_microseconds|runtime_operations|runtime_operations_latency_microseconds|runtime_operations_errors|eviction_stats_age_microseconds|device_plugin_registration_count|device_plugin_alloc_latency_microseconds|network_plugin_operations_latency_microseconds)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: scheduler_(e2e_scheduling_latency_microseconds|scheduling_algorithm_predicate_evaluation|scheduling_algorithm_priority_evaluation|scheduling_algorithm_preemption_evaluation|scheduling_algorithm_latency_microseconds|binding_latency_microseconds|scheduling_latency_seconds)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: apiserver_(request_count|request_latencies|request_latencies_summary|dropped_requests|storage_data_key_generation_latencies_microseconds|storage_transformation_failures_total|storage_transformation_latencies_microseconds|proxy_tunnel_sync_latency_secs|longrunning_gauge|registered_watchers|storage_db_total_size_in_bytes|flowcontrol_request_concurrency_limit|flowcontrol_request_concurrency_in_use)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: kubelet_docker_(operations|operations_latency_microseconds|operations_errors|operations_timeout)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: reflector_(items_per_list|items_per_watch|list_duration_seconds|lists_total|short_watches_total|watch_duration_seconds|watches_total)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: etcd_(helper_cache_hit_count|helper_cache_miss_count|helper_cache_entry_count|object_counts|request_cache_get_latencies_summary|request_cache_add_latencies_summary|request_latencies_summary)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: transformation_(transformation_latencies_microseconds|failures_total)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: (admission_quota_controller_adds|admission_quota_controller_depth|admission_quota_controller_longest_running_processor_microseconds|admission_quota_controller_queue_latency|admission_quota_controller_unfinished_work_seconds|admission_quota_controller_work_duration|APIServiceOpenAPIAggregationControllerQueue1_adds|APIServiceOpenAPIAggregationControllerQueue1_depth|APIServiceOpenAPIAggregationControllerQueue1_longest_running_processor_microseconds|APIServiceOpenAPIAggregationControllerQueue1_queue_latency|APIServiceOpenAPIAggregationControllerQueue1_retries|APIServiceOpenAPIAggregationControllerQueue1_unfinished_work_seconds|APIServiceOpenAPIAggregationControllerQueue1_work_duration|APIServiceRegistrationController_adds|APIServiceRegistrationController_depth|APIServiceRegistrationController_longest_running_processor_microseconds|APIServiceRegistrationController_queue_latency|APIServiceRegistrationController_retries|APIServiceRegistrationController_unfinished_work_seconds|APIServiceRegistrationController_work_duration|autoregister_adds|autoregister_depth|autoregister_longest_running_processor_microseconds|autoregister_queue_latency|autoregister_retries|autoregister_unfinished_work_seconds|autoregister_work_duration|AvailableConditionController_adds|AvailableConditionController_depth|AvailableConditionController_longest_running_processor_microseconds|AvailableConditionController_queue_latency|AvailableConditionController_retries|AvailableConditionController_unfinished_work_seconds|AvailableConditionController_work_duration|crd_autoregistration_controller_adds|crd_autoregistration_controller_depth|crd_autoregistration_controller_longest_running_processor_microseconds|crd_autoregistration_controller_queue_latency|crd_autoregistration_controller_retries|crd_autoregistration_controller_unfinished_work_seconds|crd_autoregistration_controller_work_duration|crdEstablishing_adds|crdEstablishing_depth|crdEstablishing_longest_running_processor_microseconds|crdEstablishing_queue_latency|crdEstablishing_retries|crdEstablishing_unfinished_work_seconds|crdEstablishing_work_duration|crd_finalizer_adds|crd_finalizer_depth|crd_finalizer_longest_running_processor_microseconds|crd_finalizer_queue_latency|crd_finalizer_retries|crd_finalizer_unfinished_work_seconds|crd_finalizer_work_duration|crd_naming_condition_controller_adds|crd_naming_condition_controller_depth|crd_naming_condition_controller_longest_running_processor_microseconds|crd_naming_condition_controller_queue_latency|crd_naming_condition_controller_retries|crd_naming_condition_controller_unfinished_work_seconds|crd_naming_condition_controller_work_duration|crd_openapi_controller_adds|crd_openapi_controller_depth|crd_openapi_controller_longest_running_processor_microseconds|crd_openapi_controller_queue_latency|crd_openapi_controller_retries|crd_openapi_controller_unfinished_work_seconds|crd_openapi_controller_work_duration|DiscoveryController_adds|DiscoveryController_depth|DiscoveryController_longest_running_processor_microseconds|DiscoveryController_queue_latency|DiscoveryController_retries|DiscoveryController_unfinished_work_seconds|DiscoveryController_work_duration|kubeproxy_sync_proxy_rules_latency_microseconds|non_structural_schema_condition_controller_adds|non_structural_schema_condition_controller_depth|non_structural_schema_condition_controller_longest_running_processor_microseconds|non_structural_schema_condition_controller_queue_latency|non_structural_schema_condition_controller_retries|non_structural_schema_condition_controller_unfinished_work_seconds|non_structural_schema_condition_controller_work_duration|rest_client_request_latency_seconds|storage_operation_errors_total|storage_operation_status_count)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: etcd_(debugging|disk|request|server).*\n      sourceLabels:\n      - __name__\n    port: https-metrics\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    interval: 5s\n    metricRelabelings:\n    - action: drop\n      regex: process_start_time_seconds\n      sourceLabels:\n      - __name__\n    path: /metrics/slis\n    port: https-metrics\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  jobLabel: app.kubernetes.io/name\n  namespaceSelector:\n    matchNames:\n    - kube-system\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: kube-controller-manager\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubernetesControlPlane-serviceMonitorKubeScheduler.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  labels:\n    app.kubernetes.io/component: kubernetes\n    app.kubernetes.io/name: kube-scheduler\n    app.kubernetes.io/part-of: kube-prometheus\n  name: kube-scheduler\n  namespace: monitoring\nspec:\n  endpoints:\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    interval: 30s\n    port: https-metrics\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    interval: 5s\n    metricRelabelings:\n    - action: drop\n      regex: process_start_time_seconds\n      sourceLabels:\n      - __name__\n    path: /metrics/slis\n    port: https-metrics\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  jobLabel: app.kubernetes.io/name\n  namespaceSelector:\n    matchNames:\n    - kube-system\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: kube-scheduler\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kubernetesControlPlane-serviceMonitorKubelet.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  labels:\n    app.kubernetes.io/component: kubernetes\n    app.kubernetes.io/name: kubelet\n    app.kubernetes.io/part-of: kube-prometheus\n  name: kubelet\n  namespace: monitoring\nspec:\n  endpoints:\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    honorLabels: true\n    interval: 30s\n    metricRelabelings:\n    - action: drop\n      regex: kubelet_(pod_worker_latency_microseconds|pod_start_latency_microseconds|cgroup_manager_latency_microseconds|pod_worker_start_latency_microseconds|pleg_relist_latency_microseconds|pleg_relist_interval_microseconds|runtime_operations|runtime_operations_latency_microseconds|runtime_operations_errors|eviction_stats_age_microseconds|device_plugin_registration_count|device_plugin_alloc_latency_microseconds|network_plugin_operations_latency_microseconds)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: scheduler_(e2e_scheduling_latency_microseconds|scheduling_algorithm_predicate_evaluation|scheduling_algorithm_priority_evaluation|scheduling_algorithm_preemption_evaluation|scheduling_algorithm_latency_microseconds|binding_latency_microseconds|scheduling_latency_seconds)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: apiserver_(request_count|request_latencies|request_latencies_summary|dropped_requests|storage_data_key_generation_latencies_microseconds|storage_transformation_failures_total|storage_transformation_latencies_microseconds|proxy_tunnel_sync_latency_secs|longrunning_gauge|registered_watchers|storage_db_total_size_in_bytes|flowcontrol_request_concurrency_limit|flowcontrol_request_concurrency_in_use)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: kubelet_docker_(operations|operations_latency_microseconds|operations_errors|operations_timeout)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: reflector_(items_per_list|items_per_watch|list_duration_seconds|lists_total|short_watches_total|watch_duration_seconds|watches_total)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: etcd_(helper_cache_hit_count|helper_cache_miss_count|helper_cache_entry_count|object_counts|request_cache_get_latencies_summary|request_cache_add_latencies_summary|request_latencies_summary)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: transformation_(transformation_latencies_microseconds|failures_total)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: (admission_quota_controller_adds|admission_quota_controller_depth|admission_quota_controller_longest_running_processor_microseconds|admission_quota_controller_queue_latency|admission_quota_controller_unfinished_work_seconds|admission_quota_controller_work_duration|APIServiceOpenAPIAggregationControllerQueue1_adds|APIServiceOpenAPIAggregationControllerQueue1_depth|APIServiceOpenAPIAggregationControllerQueue1_longest_running_processor_microseconds|APIServiceOpenAPIAggregationControllerQueue1_queue_latency|APIServiceOpenAPIAggregationControllerQueue1_retries|APIServiceOpenAPIAggregationControllerQueue1_unfinished_work_seconds|APIServiceOpenAPIAggregationControllerQueue1_work_duration|APIServiceRegistrationController_adds|APIServiceRegistrationController_depth|APIServiceRegistrationController_longest_running_processor_microseconds|APIServiceRegistrationController_queue_latency|APIServiceRegistrationController_retries|APIServiceRegistrationController_unfinished_work_seconds|APIServiceRegistrationController_work_duration|autoregister_adds|autoregister_depth|autoregister_longest_running_processor_microseconds|autoregister_queue_latency|autoregister_retries|autoregister_unfinished_work_seconds|autoregister_work_duration|AvailableConditionController_adds|AvailableConditionController_depth|AvailableConditionController_longest_running_processor_microseconds|AvailableConditionController_queue_latency|AvailableConditionController_retries|AvailableConditionController_unfinished_work_seconds|AvailableConditionController_work_duration|crd_autoregistration_controller_adds|crd_autoregistration_controller_depth|crd_autoregistration_controller_longest_running_processor_microseconds|crd_autoregistration_controller_queue_latency|crd_autoregistration_controller_retries|crd_autoregistration_controller_unfinished_work_seconds|crd_autoregistration_controller_work_duration|crdEstablishing_adds|crdEstablishing_depth|crdEstablishing_longest_running_processor_microseconds|crdEstablishing_queue_latency|crdEstablishing_retries|crdEstablishing_unfinished_work_seconds|crdEstablishing_work_duration|crd_finalizer_adds|crd_finalizer_depth|crd_finalizer_longest_running_processor_microseconds|crd_finalizer_queue_latency|crd_finalizer_retries|crd_finalizer_unfinished_work_seconds|crd_finalizer_work_duration|crd_naming_condition_controller_adds|crd_naming_condition_controller_depth|crd_naming_condition_controller_longest_running_processor_microseconds|crd_naming_condition_controller_queue_latency|crd_naming_condition_controller_retries|crd_naming_condition_controller_unfinished_work_seconds|crd_naming_condition_controller_work_duration|crd_openapi_controller_adds|crd_openapi_controller_depth|crd_openapi_controller_longest_running_processor_microseconds|crd_openapi_controller_queue_latency|crd_openapi_controller_retries|crd_openapi_controller_unfinished_work_seconds|crd_openapi_controller_work_duration|DiscoveryController_adds|DiscoveryController_depth|DiscoveryController_longest_running_processor_microseconds|DiscoveryController_queue_latency|DiscoveryController_retries|DiscoveryController_unfinished_work_seconds|DiscoveryController_work_duration|kubeproxy_sync_proxy_rules_latency_microseconds|non_structural_schema_condition_controller_adds|non_structural_schema_condition_controller_depth|non_structural_schema_condition_controller_longest_running_processor_microseconds|non_structural_schema_condition_controller_queue_latency|non_structural_schema_condition_controller_retries|non_structural_schema_condition_controller_unfinished_work_seconds|non_structural_schema_condition_controller_work_duration|rest_client_request_latency_seconds|storage_operation_errors_total|storage_operation_status_count)\n      sourceLabels:\n      - __name__\n    port: https-metrics\n    relabelings:\n    - action: replace\n      sourceLabels:\n      - __metrics_path__\n      targetLabel: metrics_path\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    honorLabels: true\n    honorTimestamps: false\n    interval: 30s\n    metricRelabelings:\n    - action: drop\n      regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s)\n      sourceLabels:\n      - __name__\n    - action: drop\n      regex: (container_spec_.*|container_file_descriptors|container_sockets|container_threads_max|container_threads|container_start_time_seconds|container_last_seen);;\n      sourceLabels:\n      - __name__\n      - pod\n      - namespace\n    - action: drop\n      regex: (container_blkio_device_usage_total);.+\n      sourceLabels:\n      - __name__\n      - container\n    path: /metrics/cadvisor\n    port: https-metrics\n    relabelings:\n    - action: replace\n      sourceLabels:\n      - __metrics_path__\n      targetLabel: metrics_path\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    honorLabels: true\n    interval: 30s\n    path: /metrics/probes\n    port: https-metrics\n    relabelings:\n    - action: replace\n      sourceLabels:\n      - __metrics_path__\n      targetLabel: metrics_path\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    honorLabels: true\n    interval: 5s\n    metricRelabelings:\n    - action: drop\n      regex: process_start_time_seconds\n      sourceLabels:\n      - __name__\n    path: /metrics/slis\n    port: https-metrics\n    relabelings:\n    - action: replace\n      sourceLabels:\n      - __metrics_path__\n      targetLabel: metrics_path\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  jobLabel: app.kubernetes.io/name\n  namespaceSelector:\n    matchNames:\n    - kube-system\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: kubelet\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/kustomization.yaml",
    "content": "# Code generated by update.sh, DO NOT EDIT.\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- blackboxExporter-clusterRole.yaml\n- blackboxExporter-clusterRoleBinding.yaml\n- blackboxExporter-configuration.yaml\n- blackboxExporter-deployment.yaml\n- blackboxExporter-networkPolicy.yaml\n- blackboxExporter-service.yaml\n- blackboxExporter-serviceAccount.yaml\n- blackboxExporter-serviceMonitor.yaml\n- grafana-config.yaml\n- grafana-dashboardDatasources.yaml\n- grafana-dashboardDefinitions.yaml\n- grafana-dashboardSources.yaml\n- grafana-deployment.yaml\n- grafana-networkPolicy.yaml\n- grafana-prometheusRule.yaml\n- grafana-service.yaml\n- grafana-serviceAccount.yaml\n- grafana-serviceMonitor.yaml\n- kubePrometheus-prometheusRule.yaml\n- kubernetesControlPlane-prometheusRule.yaml\n- kubernetesControlPlane-serviceMonitorApiserver.yaml\n- kubernetesControlPlane-serviceMonitorCoreDNS.yaml\n- kubernetesControlPlane-serviceMonitorKubeControllerManager.yaml\n- kubernetesControlPlane-serviceMonitorKubelet.yaml\n- kubernetesControlPlane-serviceMonitorKubeScheduler.yaml\n- kubeStateMetrics-clusterRole.yaml\n- kubeStateMetrics-clusterRoleBinding.yaml\n- kubeStateMetrics-deployment.yaml\n- kubeStateMetrics-networkPolicy.yaml\n- kubeStateMetrics-prometheusRule.yaml\n- kubeStateMetrics-service.yaml\n- kubeStateMetrics-serviceAccount.yaml\n- kubeStateMetrics-serviceMonitor.yaml\n- nodeExporter-clusterRole.yaml\n- nodeExporter-clusterRoleBinding.yaml\n- nodeExporter-daemonset.yaml\n- nodeExporter-networkPolicy.yaml\n- nodeExporter-prometheusRule.yaml\n- nodeExporter-service.yaml\n- nodeExporter-serviceAccount.yaml\n- nodeExporter-serviceMonitor.yaml\n- prometheus-clusterRole.yaml\n- prometheus-clusterRoleBinding.yaml\n- prometheus-networkPolicy.yaml\n- prometheus-prometheus.yaml\n- prometheus-prometheusRule.yaml\n- prometheus-roleBindingConfig.yaml\n- prometheus-roleBindingSpecificNamespaces.yaml\n- prometheus-roleConfig.yaml\n- prometheus-roleSpecificNamespaces.yaml\n- prometheus-service.yaml\n- prometheus-serviceAccount.yaml\n- prometheus-serviceMonitor.yaml\n- prometheusAdapter-clusterRole.yaml\n- prometheusAdapter-clusterRoleAggregatedMetricsReader.yaml\n- prometheusAdapter-clusterRoleBinding.yaml\n- prometheusAdapter-clusterRoleBindingDelegator.yaml\n- prometheusAdapter-clusterRoleServerResources.yaml\n- prometheusAdapter-configMap.yaml\n- prometheusAdapter-deployment.yaml\n- prometheusAdapter-networkPolicy.yaml\n- prometheusAdapter-podDisruptionBudget.yaml\n- prometheusAdapter-roleBindingAuthReader.yaml\n- prometheusAdapter-service.yaml\n- prometheusAdapter-serviceAccount.yaml\n- prometheusAdapter-serviceMonitor.yaml\n- prometheusOperator-clusterRole.yaml\n- prometheusOperator-clusterRoleBinding.yaml\n- prometheusOperator-deployment.yaml\n- prometheusOperator-networkPolicy.yaml\n- prometheusOperator-prometheusRule.yaml\n- prometheusOperator-service.yaml\n- prometheusOperator-serviceAccount.yaml\n- prometheusOperator-serviceMonitor.yaml\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/nodeExporter-clusterRole.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: node-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 1.9.1\n  name: node-exporter\nrules:\n- apiGroups:\n  - authentication.k8s.io\n  resources:\n  - tokenreviews\n  verbs:\n  - create\n- apiGroups:\n  - authorization.k8s.io\n  resources:\n  - subjectaccessreviews\n  verbs:\n  - create\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/nodeExporter-clusterRoleBinding.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: node-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 1.9.1\n  name: node-exporter\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: node-exporter\nsubjects:\n- kind: ServiceAccount\n  name: node-exporter\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/nodeExporter-daemonset.yaml",
    "content": "apiVersion: apps/v1\nkind: DaemonSet\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: node-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 1.9.1\n  name: node-exporter\n  namespace: monitoring\nspec:\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: exporter\n      app.kubernetes.io/name: node-exporter\n      app.kubernetes.io/part-of: kube-prometheus\n  template:\n    metadata:\n      annotations:\n        kubectl.kubernetes.io/default-container: node-exporter\n      labels:\n        app.kubernetes.io/component: exporter\n        app.kubernetes.io/name: node-exporter\n        app.kubernetes.io/part-of: kube-prometheus\n        app.kubernetes.io/version: 1.9.1\n    spec:\n      automountServiceAccountToken: true\n      containers:\n      - args:\n        - --web.listen-address=127.0.0.1:9101\n        - --path.sysfs=/host/sys\n        - --path.rootfs=/host/root\n        - --path.procfs=/host/root/proc\n        - --path.udev.data=/host/root/run/udev/data\n        - --no-collector.wifi\n        - --no-collector.hwmon\n        - --no-collector.btrfs\n        - --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|run/k3s/containerd/.+|var/lib/docker/.+|var/lib/kubelet/pods/.+)($|/)\n        - --collector.netclass.ignored-devices=^(veth.*|[a-f0-9]{15})$\n        - --collector.netdev.device-exclude=^(veth.*|[a-f0-9]{15})$\n        image: quay.io/prometheus/node-exporter:v1.9.1\n        name: node-exporter\n        resources:\n          limits:\n            cpu: 250m\n            memory: 180Mi\n          requests:\n            cpu: 102m\n            memory: 180Mi\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            add:\n            - SYS_TIME\n            drop:\n            - ALL\n          readOnlyRootFilesystem: true\n        volumeMounts:\n        - mountPath: /host/sys\n          mountPropagation: HostToContainer\n          name: sys\n          readOnly: true\n        - mountPath: /host/root\n          mountPropagation: HostToContainer\n          name: root\n          readOnly: true\n      - args:\n        - --secure-listen-address=[$(IP)]:9100\n        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305\n        - --upstream=http://127.0.0.1:9101/\n        env:\n        - name: IP\n          valueFrom:\n            fieldRef:\n              fieldPath: status.podIP\n        image: quay.io/brancz/kube-rbac-proxy:v0.19.1\n        name: kube-rbac-proxy\n        ports:\n        - containerPort: 9100\n          hostPort: 9100\n          name: https\n        resources:\n          limits:\n            cpu: 20m\n            memory: 40Mi\n          requests:\n            cpu: 10m\n            memory: 20Mi\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n          readOnlyRootFilesystem: true\n          runAsGroup: 65532\n          runAsNonRoot: true\n          runAsUser: 65532\n          seccompProfile:\n            type: RuntimeDefault\n      hostNetwork: true\n      hostPID: true\n      nodeSelector:\n        kubernetes.io/os: linux\n      priorityClassName: system-cluster-critical\n      securityContext:\n        runAsGroup: 65534\n        runAsNonRoot: true\n        runAsUser: 65534\n      serviceAccountName: node-exporter\n      tolerations:\n      - operator: Exists\n      volumes:\n      - hostPath:\n          path: /sys\n        name: sys\n      - hostPath:\n          path: /\n        name: root\n  updateStrategy:\n    rollingUpdate:\n      maxUnavailable: 10%\n    type: RollingUpdate\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/nodeExporter-networkPolicy.yaml",
    "content": "apiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: node-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 1.9.1\n  name: node-exporter\n  namespace: monitoring\nspec:\n  egress:\n  - {}\n  ingress:\n  - from:\n    - podSelector:\n        matchLabels:\n          app.kubernetes.io/name: prometheus\n    ports:\n    - port: 9100\n      protocol: TCP\n  podSelector:\n    matchLabels:\n      app.kubernetes.io/component: exporter\n      app.kubernetes.io/name: node-exporter\n      app.kubernetes.io/part-of: kube-prometheus\n  policyTypes:\n  - Egress\n  - Ingress\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/nodeExporter-prometheusRule.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: node-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 1.9.1\n    prometheus: k8s\n    role: alert-rules\n  name: node-exporter-rules\n  namespace: monitoring\nspec:\n  groups:\n  - name: node-exporter\n    rules:\n    - alert: NodeFilesystemSpaceFillingUp\n      annotations:\n        description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf \"%.2f\" $value }}% available space left and is filling up.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemspacefillingup\n        summary: Filesystem is predicted to run out of space within the next 24 hours.\n      expr: |\n        (\n          node_filesystem_avail_bytes{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} / node_filesystem_size_bytes{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} * 100 < 15\n        and\n          predict_linear(node_filesystem_avail_bytes{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"}[6h], 24*60*60) < 0\n        and\n          node_filesystem_readonly{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} == 0\n        )\n      for: 1h\n      labels:\n        severity: warning\n    - alert: NodeFilesystemSpaceFillingUp\n      annotations:\n        description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf \"%.2f\" $value }}% available space left and is filling up fast.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemspacefillingup\n        summary: Filesystem is predicted to run out of space within the next 4 hours.\n      expr: |\n        (\n          node_filesystem_avail_bytes{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} / node_filesystem_size_bytes{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} * 100 < 10\n        and\n          predict_linear(node_filesystem_avail_bytes{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"}[6h], 4*60*60) < 0\n        and\n          node_filesystem_readonly{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} == 0\n        )\n      for: 1h\n      labels:\n        severity: critical\n    - alert: NodeFilesystemAlmostOutOfSpace\n      annotations:\n        description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf \"%.2f\" $value }}% available space left.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemalmostoutofspace\n        summary: Filesystem has less than 5% space left.\n      expr: |\n        (\n          node_filesystem_avail_bytes{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} / node_filesystem_size_bytes{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} * 100 < 5\n        and\n          node_filesystem_readonly{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} == 0\n        )\n      for: 30m\n      labels:\n        severity: warning\n    - alert: NodeFilesystemAlmostOutOfSpace\n      annotations:\n        description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf \"%.2f\" $value }}% available space left.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemalmostoutofspace\n        summary: Filesystem has less than 3% space left.\n      expr: |\n        (\n          node_filesystem_avail_bytes{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} / node_filesystem_size_bytes{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} * 100 < 3\n        and\n          node_filesystem_readonly{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} == 0\n        )\n      for: 30m\n      labels:\n        severity: critical\n    - alert: NodeFilesystemFilesFillingUp\n      annotations:\n        description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf \"%.2f\" $value }}% available inodes left and is filling up.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemfilesfillingup\n        summary: Filesystem is predicted to run out of inodes within the next 24 hours.\n      expr: |\n        (\n          node_filesystem_files_free{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} / node_filesystem_files{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} * 100 < 40\n        and\n          predict_linear(node_filesystem_files_free{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"}[6h], 24*60*60) < 0\n        and\n          node_filesystem_readonly{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} == 0\n        )\n      for: 1h\n      labels:\n        severity: warning\n    - alert: NodeFilesystemFilesFillingUp\n      annotations:\n        description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf \"%.2f\" $value }}% available inodes left and is filling up fast.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemfilesfillingup\n        summary: Filesystem is predicted to run out of inodes within the next 4 hours.\n      expr: |\n        (\n          node_filesystem_files_free{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} / node_filesystem_files{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} * 100 < 20\n        and\n          predict_linear(node_filesystem_files_free{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"}[6h], 4*60*60) < 0\n        and\n          node_filesystem_readonly{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} == 0\n        )\n      for: 1h\n      labels:\n        severity: critical\n    - alert: NodeFilesystemAlmostOutOfFiles\n      annotations:\n        description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf \"%.2f\" $value }}% available inodes left.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemalmostoutoffiles\n        summary: Filesystem has less than 5% inodes left.\n      expr: |\n        (\n          node_filesystem_files_free{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} / node_filesystem_files{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} * 100 < 5\n        and\n          node_filesystem_readonly{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} == 0\n        )\n      for: 1h\n      labels:\n        severity: warning\n    - alert: NodeFilesystemAlmostOutOfFiles\n      annotations:\n        description: Filesystem on {{ $labels.device }}, mounted on {{ $labels.mountpoint }}, at {{ $labels.instance }} has only {{ printf \"%.2f\" $value }}% available inodes left.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemalmostoutoffiles\n        summary: Filesystem has less than 3% inodes left.\n      expr: |\n        (\n          node_filesystem_files_free{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} / node_filesystem_files{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} * 100 < 3\n        and\n          node_filesystem_readonly{job=\"node-exporter\",fstype!=\"\",mountpoint!=\"\"} == 0\n        )\n      for: 1h\n      labels:\n        severity: critical\n    - alert: NodeNetworkReceiveErrs\n      annotations:\n        description: '{{ $labels.instance }} interface {{ $labels.device }} has encountered {{ printf \"%.0f\" $value }} receive errors in the last two minutes.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodenetworkreceiveerrs\n        summary: Network interface is reporting many receive errors.\n      expr: |\n        rate(node_network_receive_errs_total{job=\"node-exporter\"}[2m]) / rate(node_network_receive_packets_total{job=\"node-exporter\"}[2m]) > 0.01\n      for: 1h\n      labels:\n        severity: warning\n    - alert: NodeNetworkTransmitErrs\n      annotations:\n        description: '{{ $labels.instance }} interface {{ $labels.device }} has encountered {{ printf \"%.0f\" $value }} transmit errors in the last two minutes.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodenetworktransmiterrs\n        summary: Network interface is reporting many transmit errors.\n      expr: |\n        rate(node_network_transmit_errs_total{job=\"node-exporter\"}[2m]) / rate(node_network_transmit_packets_total{job=\"node-exporter\"}[2m]) > 0.01\n      for: 1h\n      labels:\n        severity: warning\n    - alert: NodeHighNumberConntrackEntriesUsed\n      annotations:\n        description: '{{ $labels.instance }} {{ $value | humanizePercentage }} of conntrack entries are used.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodehighnumberconntrackentriesused\n        summary: Number of conntrack are getting close to the limit.\n      expr: |\n        (node_nf_conntrack_entries{job=\"node-exporter\"} / node_nf_conntrack_entries_limit) > 0.75\n      labels:\n        severity: warning\n    - alert: NodeTextFileCollectorScrapeError\n      annotations:\n        description: Node Exporter text file collector on {{ $labels.instance }} failed to scrape.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodetextfilecollectorscrapeerror\n        summary: Node Exporter text file collector failed to scrape.\n      expr: |\n        node_textfile_scrape_error{job=\"node-exporter\"} == 1\n      labels:\n        severity: warning\n    - alert: NodeClockSkewDetected\n      annotations:\n        description: Clock at {{ $labels.instance }} is out of sync by more than 0.05s. Ensure NTP is configured correctly on this host.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodeclockskewdetected\n        summary: Clock skew detected.\n      expr: |\n        (\n          node_timex_offset_seconds{job=\"node-exporter\"} > 0.05\n        and\n          deriv(node_timex_offset_seconds{job=\"node-exporter\"}[5m]) >= 0\n        )\n        or\n        (\n          node_timex_offset_seconds{job=\"node-exporter\"} < -0.05\n        and\n          deriv(node_timex_offset_seconds{job=\"node-exporter\"}[5m]) <= 0\n        )\n      for: 10m\n      labels:\n        severity: warning\n    - alert: NodeClockNotSynchronising\n      annotations:\n        description: Clock at {{ $labels.instance }} is not synchronising. Ensure NTP is configured on this host.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodeclocknotsynchronising\n        summary: Clock not synchronising.\n      expr: |\n        min_over_time(node_timex_sync_status{job=\"node-exporter\"}[5m]) == 0\n        and\n        node_timex_maxerror_seconds{job=\"node-exporter\"} >= 16\n      for: 10m\n      labels:\n        severity: warning\n    - alert: NodeRAIDDegraded\n      annotations:\n        description: RAID array '{{ $labels.device }}' at {{ $labels.instance }} is in degraded state due to one or more disks failures. Number of spare drives is insufficient to fix issue automatically.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/noderaiddegraded\n        summary: RAID Array is degraded.\n      expr: |\n        node_md_disks_required{job=\"node-exporter\",device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"} - ignoring (state) (node_md_disks{state=\"active\",job=\"node-exporter\",device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}) > 0\n      for: 15m\n      labels:\n        severity: critical\n    - alert: NodeRAIDDiskFailure\n      annotations:\n        description: At least one device in RAID array at {{ $labels.instance }} failed. Array '{{ $labels.device }}' needs attention and possibly a disk swap.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/noderaiddiskfailure\n        summary: Failed device in RAID array.\n      expr: |\n        node_md_disks{state=\"failed\",job=\"node-exporter\",device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"} > 0\n      labels:\n        severity: warning\n    - alert: NodeFileDescriptorLimit\n      annotations:\n        description: File descriptors limit at {{ $labels.instance }} is currently at {{ printf \"%.2f\" $value }}%.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefiledescriptorlimit\n        summary: Kernel is predicted to exhaust file descriptors limit soon.\n      expr: |\n        (\n          node_filefd_allocated{job=\"node-exporter\"} * 100 / node_filefd_maximum{job=\"node-exporter\"} > 70\n        )\n      for: 15m\n      labels:\n        severity: warning\n    - alert: NodeFileDescriptorLimit\n      annotations:\n        description: File descriptors limit at {{ $labels.instance }} is currently at {{ printf \"%.2f\" $value }}%.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefiledescriptorlimit\n        summary: Kernel is predicted to exhaust file descriptors limit soon.\n      expr: |\n        (\n          node_filefd_allocated{job=\"node-exporter\"} * 100 / node_filefd_maximum{job=\"node-exporter\"} > 90\n        )\n      for: 15m\n      labels:\n        severity: critical\n    - alert: NodeCPUHighUsage\n      annotations:\n        description: |\n          CPU usage at {{ $labels.instance }} has been above 90% for the last 15 minutes, is currently at {{ printf \"%.2f\" $value }}%.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodecpuhighusage\n        summary: High CPU usage.\n      expr: |\n        sum without(mode) (avg without (cpu) (rate(node_cpu_seconds_total{job=\"node-exporter\", mode!~\"idle|iowait\"}[2m]))) * 100 > 90\n      for: 15m\n      labels:\n        severity: info\n    - alert: NodeSystemSaturation\n      annotations:\n        description: |\n          System load per core at {{ $labels.instance }} has been above 2 for the last 15 minutes, is currently at {{ printf \"%.2f\" $value }}.\n          This might indicate this instance resources saturation and can cause it becoming unresponsive.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodesystemsaturation\n        summary: System saturated, load per core is very high.\n      expr: |\n        node_load1{job=\"node-exporter\"}\n        / count without (cpu, mode) (node_cpu_seconds_total{job=\"node-exporter\", mode=\"idle\"}) > 2\n      for: 15m\n      labels:\n        severity: warning\n    - alert: NodeMemoryMajorPagesFaults\n      annotations:\n        description: |\n          Memory major pages are occurring at very high rate at {{ $labels.instance }}, 500 major page faults per second for the last 15 minutes, is currently at {{ printf \"%.2f\" $value }}.\n          Please check that there is enough memory available at this instance.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodememorymajorpagesfaults\n        summary: Memory major page faults are occurring at very high rate.\n      expr: |\n        rate(node_vmstat_pgmajfault{job=\"node-exporter\"}[5m]) > 500\n      for: 15m\n      labels:\n        severity: warning\n    - alert: NodeMemoryHighUtilization\n      annotations:\n        description: |\n          Memory is filling up at {{ $labels.instance }}, has been above 90% for the last 15 minutes, is currently at {{ printf \"%.2f\" $value }}%.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodememoryhighutilization\n        summary: Host is running out of memory.\n      expr: |\n        100 - (node_memory_MemAvailable_bytes{job=\"node-exporter\"} / node_memory_MemTotal_bytes{job=\"node-exporter\"} * 100) > 90\n      for: 15m\n      labels:\n        severity: warning\n    - alert: NodeDiskIOSaturation\n      annotations:\n        description: |\n          Disk IO queue (aqu-sq) is high on {{ $labels.device }} at {{ $labels.instance }}, has been above 10 for the last 30 minutes, is currently at {{ printf \"%.2f\" $value }}.\n          This symptom might indicate disk saturation.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodediskiosaturation\n        summary: Disk IO queue is high.\n      expr: |\n        rate(node_disk_io_time_weighted_seconds_total{job=\"node-exporter\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[5m]) > 10\n      for: 30m\n      labels:\n        severity: warning\n    - alert: NodeSystemdServiceFailed\n      annotations:\n        description: Systemd service {{ $labels.name }} has entered failed state at {{ $labels.instance }}\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodesystemdservicefailed\n        summary: Systemd service has entered failed state.\n      expr: |\n        node_systemd_unit_state{job=\"node-exporter\", state=\"failed\"} == 1\n      for: 5m\n      labels:\n        severity: warning\n    - alert: NodeSystemdServiceCrashlooping\n      annotations:\n        description: Systemd service {{ $labels.name }} has being restarted too many times at {{ $labels.instance }} for the last 15 minutes. Please check if service is crash looping.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodesystemdservicecrashlooping\n        summary: Systemd service keeps restaring, possibly crash looping.\n      expr: |\n        increase(node_systemd_service_restart_total{job=\"node-exporter\"}[5m]) > 2\n      for: 15m\n      labels:\n        severity: warning\n    - alert: NodeBondingDegraded\n      annotations:\n        description: Bonding interface {{ $labels.master }} on {{ $labels.instance }} is in degraded state due to one or more slave failures.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodebondingdegraded\n        summary: Bonding interface is degraded\n      expr: |\n        (node_bonding_slaves - node_bonding_active) != 0\n      for: 5m\n      labels:\n        severity: warning\n  - name: node-exporter.rules\n    rules:\n    - expr: |\n        count without (cpu, mode) (\n          node_cpu_seconds_total{job=\"node-exporter\",mode=\"idle\"}\n        )\n      record: instance:node_num_cpu:sum\n    - expr: |\n        1 - avg without (cpu) (\n          sum without (mode) (rate(node_cpu_seconds_total{job=\"node-exporter\", mode=~\"idle|iowait|steal\"}[5m]))\n        )\n      record: instance:node_cpu_utilisation:rate5m\n    - expr: |\n        (\n          node_load1{job=\"node-exporter\"}\n        /\n          instance:node_num_cpu:sum{job=\"node-exporter\"}\n        )\n      record: instance:node_load1_per_cpu:ratio\n    - expr: |\n        1 - (\n          (\n            node_memory_MemAvailable_bytes{job=\"node-exporter\"}\n            or\n            (\n              node_memory_Buffers_bytes{job=\"node-exporter\"}\n              +\n              node_memory_Cached_bytes{job=\"node-exporter\"}\n              +\n              node_memory_MemFree_bytes{job=\"node-exporter\"}\n              +\n              node_memory_Slab_bytes{job=\"node-exporter\"}\n            )\n          )\n        /\n          node_memory_MemTotal_bytes{job=\"node-exporter\"}\n        )\n      record: instance:node_memory_utilisation:ratio\n    - expr: |\n        rate(node_vmstat_pgmajfault{job=\"node-exporter\"}[5m])\n      record: instance:node_vmstat_pgmajfault:rate5m\n    - expr: |\n        rate(node_disk_io_time_seconds_total{job=\"node-exporter\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[5m])\n      record: instance_device:node_disk_io_time_seconds:rate5m\n    - expr: |\n        rate(node_disk_io_time_weighted_seconds_total{job=\"node-exporter\", device=~\"(/dev/)?(mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|md.+|dasd.+)\"}[5m])\n      record: instance_device:node_disk_io_time_weighted_seconds:rate5m\n    - expr: |\n        sum without (device) (\n          rate(node_network_receive_bytes_total{job=\"node-exporter\", device!=\"lo\"}[5m])\n        )\n      record: instance:node_network_receive_bytes_excluding_lo:rate5m\n    - expr: |\n        sum without (device) (\n          rate(node_network_transmit_bytes_total{job=\"node-exporter\", device!=\"lo\"}[5m])\n        )\n      record: instance:node_network_transmit_bytes_excluding_lo:rate5m\n    - expr: |\n        sum without (device) (\n          rate(node_network_receive_drop_total{job=\"node-exporter\", device!=\"lo\"}[5m])\n        )\n      record: instance:node_network_receive_drop_excluding_lo:rate5m\n    - expr: |\n        sum without (device) (\n          rate(node_network_transmit_drop_total{job=\"node-exporter\", device!=\"lo\"}[5m])\n        )\n      record: instance:node_network_transmit_drop_excluding_lo:rate5m\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/nodeExporter-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: node-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 1.9.1\n  name: node-exporter\n  namespace: monitoring\nspec:\n  clusterIP: None\n  ports:\n  - name: https\n    port: 9100\n    targetPort: https\n  selector:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: node-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/nodeExporter-serviceAccount.yaml",
    "content": "apiVersion: v1\nautomountServiceAccountToken: false\nkind: ServiceAccount\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: node-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 1.9.1\n  name: node-exporter\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/nodeExporter-serviceMonitor.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  labels:\n    app.kubernetes.io/component: exporter\n    app.kubernetes.io/name: node-exporter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 1.9.1\n  name: node-exporter\n  namespace: monitoring\nspec:\n  endpoints:\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    interval: 15s\n    port: https\n    relabelings:\n    - action: replace\n      regex: (.*)\n      replacement: $1\n      sourceLabels:\n      - __meta_kubernetes_pod_node_name\n      targetLabel: instance\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  jobLabel: app.kubernetes.io/name\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: exporter\n      app.kubernetes.io/name: node-exporter\n      app.kubernetes.io/part-of: kube-prometheus\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheus-clusterRole.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 3.5.0\n  name: prometheus-k8s\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - nodes/metrics\n  verbs:\n  - get\n- nonResourceURLs:\n  - /metrics\n  - /metrics/slis\n  verbs:\n  - get\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheus-clusterRoleBinding.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 3.5.0\n  name: prometheus-k8s\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: prometheus-k8s\nsubjects:\n- kind: ServiceAccount\n  name: prometheus-k8s\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheus-networkPolicy.yaml",
    "content": "apiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 3.5.0\n  name: prometheus-k8s\n  namespace: monitoring\nspec:\n  egress:\n  - {}\n  ingress:\n  - from:\n    - podSelector:\n        matchLabels:\n          app.kubernetes.io/name: prometheus\n    ports:\n    - port: 9090\n      protocol: TCP\n    - port: 8080\n      protocol: TCP\n  - from:\n    - podSelector:\n        matchLabels:\n          app.kubernetes.io/name: prometheus-adapter\n    ports:\n    - port: 9090\n      protocol: TCP\n  - from:\n    - podSelector:\n        matchLabels:\n          app.kubernetes.io/name: grafana\n    ports:\n    - port: 9090\n      protocol: TCP\n  podSelector:\n    matchLabels:\n      app.kubernetes.io/component: prometheus\n      app.kubernetes.io/instance: k8s\n      app.kubernetes.io/name: prometheus\n      app.kubernetes.io/part-of: kube-prometheus\n  policyTypes:\n  - Egress\n  - Ingress\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheus-prometheus.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: Prometheus\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 3.5.0\n  name: k8s\n  namespace: monitoring\nspec:\n  alerting:\n    alertmanagers:\n    - apiVersion: v2\n      name: alertmanager-main\n      namespace: monitoring\n      port: web\n  enableFeatures: []\n  externalLabels: {}\n  image: quay.io/prometheus/prometheus:v3.5.0\n  nodeSelector:\n    kubernetes.io/os: linux\n  podMetadata:\n    labels:\n      app.kubernetes.io/component: prometheus\n      app.kubernetes.io/instance: k8s\n      app.kubernetes.io/name: prometheus\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 3.5.0\n  podMonitorNamespaceSelector: {}\n  podMonitorSelector: {}\n  probeNamespaceSelector: {}\n  probeSelector: {}\n  replicas: 2\n  resources:\n    requests:\n      memory: 400Mi\n  ruleNamespaceSelector: {}\n  ruleSelector: {}\n  scrapeConfigNamespaceSelector: {}\n  scrapeConfigSelector: {}\n  securityContext:\n    fsGroup: 2000\n    runAsNonRoot: true\n    runAsUser: 1000\n  serviceAccountName: prometheus-k8s\n  serviceMonitorNamespaceSelector: {}\n  serviceMonitorSelector: {}\n  version: 3.5.0\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheus-prometheusRule.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 3.5.0\n    prometheus: k8s\n    role: alert-rules\n  name: prometheus-k8s-prometheus-rules\n  namespace: monitoring\nspec:\n  groups:\n  - name: prometheus\n    rules:\n    - alert: PrometheusBadConfig\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has failed to reload its configuration.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusbadconfig\n        summary: Failed Prometheus configuration reload.\n      expr: |\n        # Without max_over_time, failed scrapes could create false negatives, see\n        # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details.\n        max_over_time(prometheus_config_last_reload_successful{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) == 0\n      for: 10m\n      labels:\n        severity: critical\n    - alert: PrometheusSDRefreshFailure\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has failed to refresh SD with mechanism {{$labels.mechanism}}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheussdrefreshfailure\n        summary: Failed Prometheus SD refresh.\n      expr: |\n        increase(prometheus_sd_refresh_failures_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[10m]) > 0\n      for: 20m\n      labels:\n        severity: warning\n    - alert: PrometheusKubernetesListWatchFailures\n      annotations:\n        description: Kubernetes service discovery of Prometheus {{$labels.namespace}}/{{$labels.pod}} is experiencing {{ printf \"%.0f\" $value }} failures with LIST/WATCH requests to the Kubernetes API in the last 5 minutes.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheuskuberneteslistwatchfailures\n        summary: Requests in Kubernetes SD are failing.\n      expr: |\n        increase(prometheus_sd_kubernetes_failures_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) > 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: PrometheusNotificationQueueRunningFull\n      annotations:\n        description: Alert notification queue of Prometheus {{$labels.namespace}}/{{$labels.pod}} is running full.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusnotificationqueuerunningfull\n        summary: Prometheus alert notification queue predicted to run full in less than 30m.\n      expr: |\n        # Without min_over_time, failed scrapes could create false negatives, see\n        # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details.\n        (\n          predict_linear(prometheus_notifications_queue_length{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m], 60 * 30)\n        >\n          min_over_time(prometheus_notifications_queue_capacity{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m])\n        )\n      for: 15m\n      labels:\n        severity: warning\n    - alert: PrometheusErrorSendingAlertsToSomeAlertmanagers\n      annotations:\n        description: '{{ printf \"%.1f\" $value }}% of alerts sent by Prometheus {{$labels.namespace}}/{{$labels.pod}} to Alertmanager {{$labels.alertmanager}} were affected by errors.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheuserrorsendingalertstosomealertmanagers\n        summary: More than 1% of alerts sent by Prometheus to a specific Alertmanager were affected by errors.\n      expr: |\n        (\n          rate(prometheus_notifications_errors_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m])\n        /\n          rate(prometheus_notifications_sent_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m])\n        )\n        * 100\n        > 1\n      for: 15m\n      labels:\n        severity: warning\n    - alert: PrometheusNotConnectedToAlertmanagers\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} is not connected to any Alertmanagers.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusnotconnectedtoalertmanagers\n        summary: Prometheus is not connected to any Alertmanagers.\n      expr: |\n        # Without max_over_time, failed scrapes could create false negatives, see\n        # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details.\n        max_over_time(prometheus_notifications_alertmanagers_discovered{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) < 1\n      for: 10m\n      labels:\n        severity: warning\n    - alert: PrometheusTSDBReloadsFailing\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has detected {{$value | humanize}} reload failures over the last 3h.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheustsdbreloadsfailing\n        summary: Prometheus has issues reloading blocks from disk.\n      expr: |\n        increase(prometheus_tsdb_reloads_failures_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[3h]) > 0\n      for: 4h\n      labels:\n        severity: warning\n    - alert: PrometheusTSDBCompactionsFailing\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has detected {{$value | humanize}} compaction failures over the last 3h.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheustsdbcompactionsfailing\n        summary: Prometheus has issues compacting blocks.\n      expr: |\n        increase(prometheus_tsdb_compactions_failed_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[3h]) > 0\n      for: 4h\n      labels:\n        severity: warning\n    - alert: PrometheusNotIngestingSamples\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} is not ingesting samples.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusnotingestingsamples\n        summary: Prometheus is not ingesting samples.\n      expr: |\n        (\n          sum without(type) (rate(prometheus_tsdb_head_samples_appended_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m])) <= 0\n        and\n          (\n            sum without(scrape_job) (prometheus_target_metadata_cache_entries{job=\"prometheus-k8s\",namespace=\"monitoring\"}) > 0\n          or\n            sum without(rule_group) (prometheus_rule_group_rules{job=\"prometheus-k8s\",namespace=\"monitoring\"}) > 0\n          )\n        )\n      for: 10m\n      labels:\n        severity: warning\n    - alert: PrometheusDuplicateTimestamps\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} is dropping {{ printf \"%.4g\" $value  }} samples/s with different values but duplicated timestamp.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusduplicatetimestamps\n        summary: Prometheus is dropping samples with duplicate timestamps.\n      expr: |\n        rate(prometheus_target_scrapes_sample_duplicate_timestamp_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) > 0\n      for: 10m\n      labels:\n        severity: warning\n    - alert: PrometheusOutOfOrderTimestamps\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} is dropping {{ printf \"%.4g\" $value  }} samples/s with timestamps arriving out of order.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusoutofordertimestamps\n        summary: Prometheus drops samples with out-of-order timestamps.\n      expr: |\n        rate(prometheus_target_scrapes_sample_out_of_order_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) > 0\n      for: 10m\n      labels:\n        severity: warning\n    - alert: PrometheusRemoteStorageFailures\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} failed to send {{ printf \"%.1f\" $value }}% of the samples to {{ $labels.remote_name}}:{{ $labels.url }}\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusremotestoragefailures\n        summary: Prometheus fails to send samples to remote storage.\n      expr: |\n        (\n          (rate(prometheus_remote_storage_failed_samples_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) or rate(prometheus_remote_storage_samples_failed_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]))\n        /\n          (\n            (rate(prometheus_remote_storage_failed_samples_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) or rate(prometheus_remote_storage_samples_failed_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]))\n          +\n            (rate(prometheus_remote_storage_succeeded_samples_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) or rate(prometheus_remote_storage_samples_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]))\n          )\n        )\n        * 100\n        > 1\n      for: 15m\n      labels:\n        severity: critical\n    - alert: PrometheusRemoteWriteBehind\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} remote write is {{ printf \"%.1f\" $value }}s behind for {{ $labels.remote_name}}:{{ $labels.url }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusremotewritebehind\n        summary: Prometheus remote write is behind.\n      expr: |\n        # Without max_over_time, failed scrapes could create false negatives, see\n        # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details.\n        (\n          max_over_time(prometheus_remote_storage_highest_timestamp_in_seconds{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m])\n        - ignoring(remote_name, url) group_right\n          max_over_time(prometheus_remote_storage_queue_highest_sent_timestamp_seconds{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m])\n        )\n        > 120\n      for: 15m\n      labels:\n        severity: critical\n    - alert: PrometheusRemoteWriteDesiredShards\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} remote write desired shards calculation wants to run {{ $value }} shards for queue {{ $labels.remote_name}}:{{ $labels.url }}, which is more than the max of {{ printf `prometheus_remote_storage_shards_max{instance=\"%s\",job=\"prometheus-k8s\",namespace=\"monitoring\"}` $labels.instance | query | first | value }}.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusremotewritedesiredshards\n        summary: Prometheus remote write desired shards calculation wants to run more than configured max shards.\n      expr: |\n        # Without max_over_time, failed scrapes could create false negatives, see\n        # https://www.robustperception.io/alerting-on-gauges-in-prometheus-2-0 for details.\n        (\n          max_over_time(prometheus_remote_storage_shards_desired{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m])\n        >\n          max_over_time(prometheus_remote_storage_shards_max{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m])\n        )\n      for: 15m\n      labels:\n        severity: warning\n    - alert: PrometheusRuleFailures\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has failed to evaluate {{ printf \"%.0f\" $value }} rules in the last 5m.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusrulefailures\n        summary: Prometheus is failing rule evaluations.\n      expr: |\n        increase(prometheus_rule_evaluation_failures_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) > 0\n      for: 15m\n      labels:\n        severity: critical\n    - alert: PrometheusMissingRuleEvaluations\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has missed {{ printf \"%.0f\" $value }} rule group evaluations in the last 5m.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusmissingruleevaluations\n        summary: Prometheus is missing rule evaluations due to slow rule group evaluation.\n      expr: |\n        increase(prometheus_rule_group_iterations_missed_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) > 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: PrometheusTargetLimitHit\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has dropped {{ printf \"%.0f\" $value }} targets because the number of targets exceeded the configured target_limit.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheustargetlimithit\n        summary: Prometheus has dropped targets because some scrape configs have exceeded the targets limit.\n      expr: |\n        increase(prometheus_target_scrape_pool_exceeded_target_limit_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) > 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: PrometheusLabelLimitHit\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has dropped {{ printf \"%.0f\" $value }} targets because some samples exceeded the configured label_limit, label_name_length_limit or label_value_length_limit.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheuslabellimithit\n        summary: Prometheus has dropped targets because some scrape configs have exceeded the labels limit.\n      expr: |\n        increase(prometheus_target_scrape_pool_exceeded_label_limits_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) > 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: PrometheusScrapeBodySizeLimitHit\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has failed {{ printf \"%.0f\" $value }} scrapes in the last 5m because some targets exceeded the configured body_size_limit.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusscrapebodysizelimithit\n        summary: Prometheus has dropped some targets that exceeded body size limit.\n      expr: |\n        increase(prometheus_target_scrapes_exceeded_body_size_limit_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) > 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: PrometheusScrapeSampleLimitHit\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} has failed {{ printf \"%.0f\" $value }} scrapes in the last 5m because some targets exceeded the configured sample_limit.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheusscrapesamplelimithit\n        summary: Prometheus has failed scrapes that have exceeded the configured sample limit.\n      expr: |\n        increase(prometheus_target_scrapes_exceeded_sample_limit_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) > 0\n      for: 15m\n      labels:\n        severity: warning\n    - alert: PrometheusTargetSyncFailure\n      annotations:\n        description: '{{ printf \"%.0f\" $value }} targets in Prometheus {{$labels.namespace}}/{{$labels.pod}} have failed to sync because invalid configuration was supplied.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheustargetsyncfailure\n        summary: Prometheus has failed to sync targets.\n      expr: |\n        increase(prometheus_target_sync_failed_total{job=\"prometheus-k8s\",namespace=\"monitoring\"}[30m]) > 0\n      for: 5m\n      labels:\n        severity: critical\n    - alert: PrometheusHighQueryLoad\n      annotations:\n        description: Prometheus {{$labels.namespace}}/{{$labels.pod}} query API has less than 20% available capacity in its query engine for the last 15 minutes.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheushighqueryload\n        summary: Prometheus is reaching its maximum capacity serving concurrent requests.\n      expr: |\n        avg_over_time(prometheus_engine_queries{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) / max_over_time(prometheus_engine_queries_concurrent_max{job=\"prometheus-k8s\",namespace=\"monitoring\"}[5m]) > 0.8\n      for: 15m\n      labels:\n        severity: warning\n    - alert: PrometheusErrorSendingAlertsToAnyAlertmanager\n      annotations:\n        description: '{{ printf \"%.1f\" $value }}% minimum errors while sending alerts from Prometheus {{$labels.namespace}}/{{$labels.pod}} to any Alertmanager.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus/prometheuserrorsendingalertstoanyalertmanager\n        summary: Prometheus encounters more than 3% errors sending alerts to any Alertmanager.\n      expr: |\n        min without (alertmanager) (\n          rate(prometheus_notifications_errors_total{job=\"prometheus-k8s\",namespace=\"monitoring\",alertmanager!~``}[5m])\n        /\n          rate(prometheus_notifications_sent_total{job=\"prometheus-k8s\",namespace=\"monitoring\",alertmanager!~``}[5m])\n        )\n        * 100\n        > 3\n      for: 15m\n      labels:\n        severity: critical\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheus-roleBindingConfig.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 3.5.0\n  name: prometheus-k8s-config\n  namespace: monitoring\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: prometheus-k8s-config\nsubjects:\n- kind: ServiceAccount\n  name: prometheus-k8s\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheus-roleBindingSpecificNamespaces.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nitems:\n- apiVersion: rbac.authorization.k8s.io/v1\n  kind: RoleBinding\n  metadata:\n    labels:\n      app.kubernetes.io/component: prometheus\n      app.kubernetes.io/instance: k8s\n      app.kubernetes.io/name: prometheus\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 3.5.0\n    name: prometheus-k8s\n    namespace: default\n  roleRef:\n    apiGroup: rbac.authorization.k8s.io\n    kind: Role\n    name: prometheus-k8s\n  subjects:\n  - kind: ServiceAccount\n    name: prometheus-k8s\n    namespace: monitoring\n- apiVersion: rbac.authorization.k8s.io/v1\n  kind: RoleBinding\n  metadata:\n    labels:\n      app.kubernetes.io/component: prometheus\n      app.kubernetes.io/instance: k8s\n      app.kubernetes.io/name: prometheus\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 3.5.0\n    name: prometheus-k8s\n    namespace: kube-system\n  roleRef:\n    apiGroup: rbac.authorization.k8s.io\n    kind: Role\n    name: prometheus-k8s\n  subjects:\n  - kind: ServiceAccount\n    name: prometheus-k8s\n    namespace: monitoring\n- apiVersion: rbac.authorization.k8s.io/v1\n  kind: RoleBinding\n  metadata:\n    labels:\n      app.kubernetes.io/component: prometheus\n      app.kubernetes.io/instance: k8s\n      app.kubernetes.io/name: prometheus\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 3.5.0\n    name: prometheus-k8s\n    namespace: monitoring\n  roleRef:\n    apiGroup: rbac.authorization.k8s.io\n    kind: Role\n    name: prometheus-k8s\n  subjects:\n  - kind: ServiceAccount\n    name: prometheus-k8s\n    namespace: monitoring\nkind: RoleBindingList\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheus-roleConfig.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 3.5.0\n  name: prometheus-k8s-config\n  namespace: monitoring\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - configmaps\n  verbs:\n  - get\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheus-roleSpecificNamespaces.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nitems:\n- apiVersion: rbac.authorization.k8s.io/v1\n  kind: Role\n  metadata:\n    labels:\n      app.kubernetes.io/component: prometheus\n      app.kubernetes.io/instance: k8s\n      app.kubernetes.io/name: prometheus\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 3.5.0\n    name: prometheus-k8s\n    namespace: default\n  rules:\n  - apiGroups:\n    - \"\"\n    resources:\n    - services\n    - endpoints\n    - pods\n    verbs:\n    - get\n    - list\n    - watch\n  - apiGroups:\n    - extensions\n    resources:\n    - ingresses\n    verbs:\n    - get\n    - list\n    - watch\n  - apiGroups:\n    - networking.k8s.io\n    resources:\n    - ingresses\n    verbs:\n    - get\n    - list\n    - watch\n- apiVersion: rbac.authorization.k8s.io/v1\n  kind: Role\n  metadata:\n    labels:\n      app.kubernetes.io/component: prometheus\n      app.kubernetes.io/instance: k8s\n      app.kubernetes.io/name: prometheus\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 3.5.0\n    name: prometheus-k8s\n    namespace: kube-system\n  rules:\n  - apiGroups:\n    - \"\"\n    resources:\n    - services\n    - endpoints\n    - pods\n    verbs:\n    - get\n    - list\n    - watch\n  - apiGroups:\n    - extensions\n    resources:\n    - ingresses\n    verbs:\n    - get\n    - list\n    - watch\n  - apiGroups:\n    - networking.k8s.io\n    resources:\n    - ingresses\n    verbs:\n    - get\n    - list\n    - watch\n- apiVersion: rbac.authorization.k8s.io/v1\n  kind: Role\n  metadata:\n    labels:\n      app.kubernetes.io/component: prometheus\n      app.kubernetes.io/instance: k8s\n      app.kubernetes.io/name: prometheus\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 3.5.0\n    name: prometheus-k8s\n    namespace: monitoring\n  rules:\n  - apiGroups:\n    - \"\"\n    resources:\n    - services\n    - endpoints\n    - pods\n    verbs:\n    - get\n    - list\n    - watch\n  - apiGroups:\n    - extensions\n    resources:\n    - ingresses\n    verbs:\n    - get\n    - list\n    - watch\n  - apiGroups:\n    - networking.k8s.io\n    resources:\n    - ingresses\n    verbs:\n    - get\n    - list\n    - watch\nkind: RoleList\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheus-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 3.5.0\n  name: prometheus-k8s\n  namespace: monitoring\nspec:\n  ports:\n  - name: web\n    port: 9090\n    targetPort: web\n  - name: reloader-web\n    port: 8080\n    targetPort: reloader-web\n  selector:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n  sessionAffinity: ClientIP\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheus-serviceAccount.yaml",
    "content": "apiVersion: v1\nautomountServiceAccountToken: true\nkind: ServiceAccount\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 3.5.0\n  name: prometheus-k8s\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheus-serviceMonitor.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 3.5.0\n  name: prometheus-k8s\n  namespace: monitoring\nspec:\n  endpoints:\n  - interval: 30s\n    port: web\n  - interval: 30s\n    port: reloader-web\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: prometheus\n      app.kubernetes.io/instance: k8s\n      app.kubernetes.io/name: prometheus\n      app.kubernetes.io/part-of: kube-prometheus\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-clusterRole.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n  name: prometheus-adapter\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - nodes\n  - namespaces\n  - pods\n  - services\n  verbs:\n  - get\n  - list\n  - watch\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-clusterRoleAggregatedMetricsReader.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n    rbac.authorization.k8s.io/aggregate-to-admin: \"true\"\n    rbac.authorization.k8s.io/aggregate-to-edit: \"true\"\n    rbac.authorization.k8s.io/aggregate-to-view: \"true\"\n  name: system:aggregated-metrics-reader\nrules:\n- apiGroups:\n  - metrics.k8s.io\n  resources:\n  - pods\n  - nodes\n  verbs:\n  - get\n  - list\n  - watch\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-clusterRoleBinding.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n  name: prometheus-adapter\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: prometheus-adapter\nsubjects:\n- kind: ServiceAccount\n  name: prometheus-adapter\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-clusterRoleBindingDelegator.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n  name: resource-metrics:system:auth-delegator\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: system:auth-delegator\nsubjects:\n- kind: ServiceAccount\n  name: prometheus-adapter\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-clusterRoleServerResources.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n  name: resource-metrics-server-resources\nrules:\n- apiGroups:\n  - metrics.k8s.io\n  resources:\n  - '*'\n  verbs:\n  - '*'\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-configMap.yaml",
    "content": "apiVersion: v1\ndata:\n  config.yaml: |-\n    \"resourceRules\":\n      \"cpu\":\n        \"containerLabel\": \"container\"\n        \"containerQuery\": |\n          sum by (<<.GroupBy>>) (\n            irate (\n                container_cpu_usage_seconds_total{<<.LabelMatchers>>,container!=\"\",pod!=\"\"}[120s]\n            )\n          )\n        \"nodeQuery\": |\n          sum by (<<.GroupBy>>) (\n            1 - irate(\n              node_cpu_seconds_total{mode=\"idle\"}[60s]\n            )\n            * on(namespace, pod) group_left(node) (\n              node_namespace_pod:kube_pod_info:{<<.LabelMatchers>>}\n            )\n          )\n          or sum by (<<.GroupBy>>) (\n            1 - irate(\n              windows_cpu_time_total{mode=\"idle\", job=\"windows-exporter\",<<.LabelMatchers>>}[4m]\n            )\n          )\n        \"resources\":\n          \"overrides\":\n            \"namespace\":\n              \"resource\": \"namespace\"\n            \"node\":\n              \"resource\": \"node\"\n            \"pod\":\n              \"resource\": \"pod\"\n      \"memory\":\n        \"containerLabel\": \"container\"\n        \"containerQuery\": |\n          sum by (<<.GroupBy>>) (\n            container_memory_working_set_bytes{<<.LabelMatchers>>,container!=\"\",pod!=\"\"}\n          )\n        \"nodeQuery\": |\n          sum by (<<.GroupBy>>) (\n            node_memory_MemTotal_bytes{job=\"node-exporter\",<<.LabelMatchers>>}\n            -\n            node_memory_MemAvailable_bytes{job=\"node-exporter\",<<.LabelMatchers>>}\n          )\n          or sum by (<<.GroupBy>>) (\n            windows_cs_physical_memory_bytes{job=\"windows-exporter\",<<.LabelMatchers>>}\n            -\n            windows_memory_available_bytes{job=\"windows-exporter\",<<.LabelMatchers>>}\n          )\n        \"resources\":\n          \"overrides\":\n            \"instance\":\n              \"resource\": \"node\"\n            \"namespace\":\n              \"resource\": \"namespace\"\n            \"pod\":\n              \"resource\": \"pod\"\n      \"window\": \"5m\"\nkind: ConfigMap\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n  name: adapter-config\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-deployment.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n  name: prometheus-adapter\n  namespace: monitoring\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: metrics-adapter\n      app.kubernetes.io/name: prometheus-adapter\n      app.kubernetes.io/part-of: kube-prometheus\n  strategy:\n    rollingUpdate:\n      maxSurge: 1\n      maxUnavailable: 1\n  template:\n    metadata:\n      annotations:\n        checksum.config/md5: 3b1ebf7df0232d1675896f67b66373db\n      labels:\n        app.kubernetes.io/component: metrics-adapter\n        app.kubernetes.io/name: prometheus-adapter\n        app.kubernetes.io/part-of: kube-prometheus\n        app.kubernetes.io/version: 0.12.0\n    spec:\n      automountServiceAccountToken: true\n      containers:\n      - args:\n        - --cert-dir=/var/run/serving-cert\n        - --config=/etc/adapter/config.yaml\n        - --metrics-relist-interval=1m\n        - --prometheus-url=http://prometheus-k8s.monitoring.svc:9090/\n        - --secure-port=6443\n        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA\n        image: registry.k8s.io/prometheus-adapter/prometheus-adapter:v0.12.0\n        livenessProbe:\n          failureThreshold: 5\n          httpGet:\n            path: /livez\n            port: https\n            scheme: HTTPS\n          periodSeconds: 5\n        name: prometheus-adapter\n        ports:\n        - containerPort: 6443\n          name: https\n        readinessProbe:\n          failureThreshold: 5\n          httpGet:\n            path: /readyz\n            port: https\n            scheme: HTTPS\n          periodSeconds: 5\n        resources:\n          limits:\n            cpu: 250m\n            memory: 180Mi\n          requests:\n            cpu: 102m\n            memory: 180Mi\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n          readOnlyRootFilesystem: true\n          runAsNonRoot: true\n          seccompProfile:\n            type: RuntimeDefault\n        startupProbe:\n          failureThreshold: 18\n          httpGet:\n            path: /livez\n            port: https\n            scheme: HTTPS\n          periodSeconds: 10\n        volumeMounts:\n        - mountPath: /tmp\n          name: tmpfs\n          readOnly: false\n        - mountPath: /var/run/serving-cert\n          name: volume-serving-cert\n          readOnly: false\n        - mountPath: /etc/adapter\n          name: config\n          readOnly: false\n      nodeSelector:\n        kubernetes.io/os: linux\n      serviceAccountName: prometheus-adapter\n      volumes:\n      - emptyDir: {}\n        name: tmpfs\n      - emptyDir: {}\n        name: volume-serving-cert\n      - configMap:\n          name: adapter-config\n        name: config\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-networkPolicy.yaml",
    "content": "apiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n  name: prometheus-adapter\n  namespace: monitoring\nspec:\n  egress:\n  - {}\n  ingress:\n  - {}\n  podSelector:\n    matchLabels:\n      app.kubernetes.io/component: metrics-adapter\n      app.kubernetes.io/name: prometheus-adapter\n      app.kubernetes.io/part-of: kube-prometheus\n  policyTypes:\n  - Egress\n  - Ingress\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-podDisruptionBudget.yaml",
    "content": "apiVersion: policy/v1\nkind: PodDisruptionBudget\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n  name: prometheus-adapter\n  namespace: monitoring\nspec:\n  minAvailable: 1\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: metrics-adapter\n      app.kubernetes.io/name: prometheus-adapter\n      app.kubernetes.io/part-of: kube-prometheus\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-roleBindingAuthReader.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n  name: resource-metrics-auth-reader\n  namespace: kube-system\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: extension-apiserver-authentication-reader\nsubjects:\n- kind: ServiceAccount\n  name: prometheus-adapter\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n  name: prometheus-adapter\n  namespace: monitoring\nspec:\n  ports:\n  - name: https\n    port: 443\n    targetPort: 6443\n  selector:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-serviceAccount.yaml",
    "content": "apiVersion: v1\nautomountServiceAccountToken: false\nkind: ServiceAccount\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n  name: prometheus-adapter\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusAdapter-serviceMonitor.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  labels:\n    app.kubernetes.io/component: metrics-adapter\n    app.kubernetes.io/name: prometheus-adapter\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.12.0\n  name: prometheus-adapter\n  namespace: monitoring\nspec:\n  endpoints:\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    interval: 30s\n    metricRelabelings:\n    - action: drop\n      regex: (apiserver_client_certificate_.*|apiserver_envelope_.*|apiserver_flowcontrol_.*|apiserver_storage_.*|apiserver_webhooks_.*|workqueue_.*)\n      sourceLabels:\n      - __name__\n    port: https\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: metrics-adapter\n      app.kubernetes.io/name: prometheus-adapter\n      app.kubernetes.io/part-of: kube-prometheus\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusOperator-clusterRole.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  labels:\n    app.kubernetes.io/component: controller\n    app.kubernetes.io/name: prometheus-operator\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.85.0\n  name: prometheus-operator\nrules:\n- apiGroups:\n  - monitoring.coreos.com\n  resources:\n  - alertmanagers\n  - alertmanagers/finalizers\n  - alertmanagers/status\n  - alertmanagerconfigs\n  - prometheuses\n  - prometheuses/finalizers\n  - prometheuses/status\n  - prometheusagents\n  - prometheusagents/finalizers\n  - prometheusagents/status\n  - thanosrulers\n  - thanosrulers/finalizers\n  - thanosrulers/status\n  - scrapeconfigs\n  - servicemonitors\n  - servicemonitors/status\n  - podmonitors\n  - probes\n  - prometheusrules\n  verbs:\n  - '*'\n- apiGroups:\n  - apps\n  resources:\n  - statefulsets\n  verbs:\n  - '*'\n- apiGroups:\n  - \"\"\n  resources:\n  - configmaps\n  - secrets\n  verbs:\n  - '*'\n- apiGroups:\n  - \"\"\n  resources:\n  - pods\n  verbs:\n  - list\n  - delete\n- apiGroups:\n  - \"\"\n  resources:\n  - services\n  - services/finalizers\n  verbs:\n  - get\n  - create\n  - update\n  - delete\n- apiGroups:\n  - \"\"\n  resources:\n  - nodes\n  verbs:\n  - list\n  - watch\n- apiGroups:\n  - \"\"\n  resources:\n  - namespaces\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - \"\"\n  resources:\n  - events\n  verbs:\n  - patch\n  - create\n- apiGroups:\n  - networking.k8s.io\n  resources:\n  - ingresses\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - storage.k8s.io\n  resources:\n  - storageclasses\n  verbs:\n  - get\n- apiGroups:\n  - \"\"\n  resources:\n  - endpoints\n  verbs:\n  - get\n  - create\n  - update\n  - delete\n- apiGroups:\n  - authentication.k8s.io\n  resources:\n  - tokenreviews\n  verbs:\n  - create\n- apiGroups:\n  - authorization.k8s.io\n  resources:\n  - subjectaccessreviews\n  verbs:\n  - create\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusOperator-clusterRoleBinding.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: controller\n    app.kubernetes.io/name: prometheus-operator\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.85.0\n  name: prometheus-operator\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: prometheus-operator\nsubjects:\n- kind: ServiceAccount\n  name: prometheus-operator\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusOperator-deployment.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  labels:\n    app.kubernetes.io/component: controller\n    app.kubernetes.io/name: prometheus-operator\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.85.0\n  name: prometheus-operator\n  namespace: monitoring\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: controller\n      app.kubernetes.io/name: prometheus-operator\n      app.kubernetes.io/part-of: kube-prometheus\n  template:\n    metadata:\n      annotations:\n        kubectl.kubernetes.io/default-container: prometheus-operator\n      labels:\n        app.kubernetes.io/component: controller\n        app.kubernetes.io/name: prometheus-operator\n        app.kubernetes.io/part-of: kube-prometheus\n        app.kubernetes.io/version: 0.85.0\n    spec:\n      automountServiceAccountToken: true\n      containers:\n      - args:\n        - --kubelet-service=kube-system/kubelet\n        - --prometheus-config-reloader=quay.io/prometheus-operator/prometheus-config-reloader:v0.85.0\n        - --kubelet-endpoints=true\n        - --kubelet-endpointslice=false\n        env:\n        - name: GOGC\n          value: \"30\"\n        image: quay.io/prometheus-operator/prometheus-operator:v0.85.0\n        name: prometheus-operator\n        ports:\n        - containerPort: 8080\n          name: http\n        resources:\n          limits:\n            cpu: 200m\n            memory: 200Mi\n          requests:\n            cpu: 100m\n            memory: 100Mi\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n          readOnlyRootFilesystem: true\n      - args:\n        - --secure-listen-address=:8443\n        - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305\n        - --upstream=http://127.0.0.1:8080/\n        image: quay.io/brancz/kube-rbac-proxy:v0.19.1\n        name: kube-rbac-proxy\n        ports:\n        - containerPort: 8443\n          name: https\n        resources:\n          limits:\n            cpu: 20m\n            memory: 40Mi\n          requests:\n            cpu: 10m\n            memory: 20Mi\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n            - ALL\n          readOnlyRootFilesystem: true\n          runAsGroup: 65532\n          runAsNonRoot: true\n          runAsUser: 65532\n          seccompProfile:\n            type: RuntimeDefault\n      nodeSelector:\n        kubernetes.io/os: linux\n      securityContext:\n        runAsGroup: 65534\n        runAsNonRoot: true\n        runAsUser: 65534\n        seccompProfile:\n          type: RuntimeDefault\n      serviceAccountName: prometheus-operator\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusOperator-networkPolicy.yaml",
    "content": "apiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  labels:\n    app.kubernetes.io/component: controller\n    app.kubernetes.io/name: prometheus-operator\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.85.0\n  name: prometheus-operator\n  namespace: monitoring\nspec:\n  egress:\n  - {}\n  ingress:\n  - from:\n    - podSelector:\n        matchLabels:\n          app.kubernetes.io/name: prometheus\n    ports:\n    - port: 8443\n      protocol: TCP\n  podSelector:\n    matchLabels:\n      app.kubernetes.io/component: controller\n      app.kubernetes.io/name: prometheus-operator\n      app.kubernetes.io/part-of: kube-prometheus\n  policyTypes:\n  - Egress\n  - Ingress\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusOperator-prometheusRule.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  labels:\n    app.kubernetes.io/component: controller\n    app.kubernetes.io/name: prometheus-operator\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.85.0\n    prometheus: k8s\n    role: alert-rules\n  name: prometheus-operator-rules\n  namespace: monitoring\nspec:\n  groups:\n  - name: prometheus-operator\n    rules:\n    - alert: PrometheusOperatorListErrors\n      annotations:\n        description: Errors while performing List operations in controller {{$labels.controller}} in {{$labels.namespace}} namespace.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatorlisterrors\n        summary: Errors while performing list operations in controller.\n      expr: |\n        (sum by (cluster,controller,namespace) (rate(prometheus_operator_list_operations_failed_total{job=\"prometheus-operator\",namespace=\"monitoring\"}[10m])) / sum by (cluster,controller,namespace) (rate(prometheus_operator_list_operations_total{job=\"prometheus-operator\",namespace=\"monitoring\"}[10m]))) > 0.4\n      for: 15m\n      labels:\n        severity: warning\n    - alert: PrometheusOperatorWatchErrors\n      annotations:\n        description: Errors while performing watch operations in controller {{$labels.controller}} in {{$labels.namespace}} namespace.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatorwatcherrors\n        summary: Errors while performing watch operations in controller.\n      expr: |\n        (sum by (cluster,controller,namespace) (rate(prometheus_operator_watch_operations_failed_total{job=\"prometheus-operator\",namespace=\"monitoring\"}[5m])) / sum by (cluster,controller,namespace) (rate(prometheus_operator_watch_operations_total{job=\"prometheus-operator\",namespace=\"monitoring\"}[5m]))) > 0.4\n      for: 15m\n      labels:\n        severity: warning\n    - alert: PrometheusOperatorSyncFailed\n      annotations:\n        description: Controller {{ $labels.controller }} in {{ $labels.namespace }} namespace fails to reconcile {{ $value }} objects.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatorsyncfailed\n        summary: Last controller reconciliation failed\n      expr: |\n        min_over_time(prometheus_operator_syncs{status=\"failed\",job=\"prometheus-operator\",namespace=\"monitoring\"}[5m]) > 0\n      for: 10m\n      labels:\n        severity: warning\n    - alert: PrometheusOperatorReconcileErrors\n      annotations:\n        description: '{{ $value | humanizePercentage }} of reconciling operations failed for {{ $labels.controller }} controller in {{ $labels.namespace }} namespace.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatorreconcileerrors\n        summary: Errors while reconciling objects.\n      expr: |\n        (sum by (cluster,controller,namespace) (rate(prometheus_operator_reconcile_errors_total{job=\"prometheus-operator\",namespace=\"monitoring\"}[5m]))) / (sum by (cluster,controller,namespace) (rate(prometheus_operator_reconcile_operations_total{job=\"prometheus-operator\",namespace=\"monitoring\"}[5m]))) > 0.1\n      for: 10m\n      labels:\n        severity: warning\n    - alert: PrometheusOperatorStatusUpdateErrors\n      annotations:\n        description: '{{ $value | humanizePercentage }} of status update operations failed for {{ $labels.controller }} controller in {{ $labels.namespace }} namespace.'\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatorstatusupdateerrors\n        summary: Errors while updating objects status.\n      expr: |\n        (sum by (cluster,controller,namespace) (rate(prometheus_operator_status_update_errors_total{job=\"prometheus-operator\",namespace=\"monitoring\"}[5m]))) / (sum by (cluster,controller,namespace) (rate(prometheus_operator_status_update_operations_total{job=\"prometheus-operator\",namespace=\"monitoring\"}[5m]))) > 0.1\n      for: 10m\n      labels:\n        severity: warning\n    - alert: PrometheusOperatorNodeLookupErrors\n      annotations:\n        description: Errors while reconciling Prometheus in {{ $labels.namespace }} Namespace.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatornodelookuperrors\n        summary: Errors while reconciling Prometheus.\n      expr: |\n        rate(prometheus_operator_node_address_lookup_errors_total{job=\"prometheus-operator\",namespace=\"monitoring\"}[5m]) > 0.1\n      for: 10m\n      labels:\n        severity: warning\n    - alert: PrometheusOperatorNotReady\n      annotations:\n        description: Prometheus operator in {{ $labels.namespace }} namespace isn't ready to reconcile {{ $labels.controller }} resources.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatornotready\n        summary: Prometheus operator not ready\n      expr: |\n        min by (cluster,controller,namespace) (max_over_time(prometheus_operator_ready{job=\"prometheus-operator\",namespace=\"monitoring\"}[5m]) == 0)\n      for: 5m\n      labels:\n        severity: warning\n    - alert: PrometheusOperatorRejectedResources\n      annotations:\n        description: Prometheus operator in {{ $labels.namespace }} namespace rejected {{ printf \"%0.0f\" $value }} {{ $labels.controller }}/{{ $labels.resource }} resources.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/prometheusoperatorrejectedresources\n        summary: Resources rejected by Prometheus operator\n      expr: |\n        min_over_time(prometheus_operator_managed_resources{state=\"rejected\",job=\"prometheus-operator\",namespace=\"monitoring\"}[5m]) > 0\n      for: 5m\n      labels:\n        severity: warning\n  - name: config-reloaders\n    rules:\n    - alert: ConfigReloaderSidecarErrors\n      annotations:\n        description: |-\n          Errors encountered while the {{$labels.pod}} config-reloader sidecar attempts to sync config in {{$labels.namespace}} namespace.\n          As a result, configuration for service running in {{$labels.pod}} may be stale and cannot be updated anymore.\n        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/prometheus-operator/configreloadersidecarerrors\n        summary: config-reloader sidecar has not had a successful reload for 10m\n      expr: |\n        max_over_time(reloader_last_reload_successful{namespace=~\".+\"}[5m]) == 0\n      for: 10m\n      labels:\n        severity: warning\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusOperator-service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    app.kubernetes.io/component: controller\n    app.kubernetes.io/name: prometheus-operator\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.85.0\n  name: prometheus-operator\n  namespace: monitoring\nspec:\n  clusterIP: None\n  ports:\n  - name: https\n    port: 8443\n    targetPort: https\n  selector:\n    app.kubernetes.io/component: controller\n    app.kubernetes.io/name: prometheus-operator\n    app.kubernetes.io/part-of: kube-prometheus\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusOperator-serviceAccount.yaml",
    "content": "apiVersion: v1\nautomountServiceAccountToken: false\nkind: ServiceAccount\nmetadata:\n  labels:\n    app.kubernetes.io/component: controller\n    app.kubernetes.io/name: prometheus-operator\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.85.0\n  name: prometheus-operator\n  namespace: monitoring\n"
  },
  {
    "path": "hack/config/monitoring/kube-prometheus/prometheusOperator-serviceMonitor.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  labels:\n    app.kubernetes.io/component: controller\n    app.kubernetes.io/name: prometheus-operator\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: 0.85.0\n  name: prometheus-operator\n  namespace: monitoring\nspec:\n  endpoints:\n  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    honorLabels: true\n    port: https\n    scheme: https\n    tlsConfig:\n      insecureSkipVerify: true\n  selector:\n    matchLabels:\n      app.kubernetes.io/component: controller\n      app.kubernetes.io/name: prometheus-operator\n      app.kubernetes.io/part-of: kube-prometheus\n      app.kubernetes.io/version: 0.85.0\n"
  },
  {
    "path": "hack/config/monitoring/shoot/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../default\n- storageclass.yaml\n\npatches:\n- path: patch_prometheus.yaml\n# drop ServiceMonitors for control plane components (not reachable in Shoot cluster)\n- patch: |\n    apiVersion: monitoring.coreos.com/v1\n    metadata:\n      name: kube-apiserver\n      namespace: monitoring\n    kind: ServiceMonitor\n    $patch: delete\n- patch: |\n    apiVersion: monitoring.coreos.com/v1\n    metadata:\n      name: kube-controller-manager\n      namespace: monitoring\n    kind: ServiceMonitor\n    $patch: delete\n- patch: |\n    apiVersion: monitoring.coreos.com/v1\n    metadata:\n      name: kube-scheduler\n      namespace: monitoring\n    kind: ServiceMonitor\n    $patch: delete\n"
  },
  {
    "path": "hack/config/monitoring/shoot/patch_prometheus.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: Prometheus\nmetadata:\n  name: k8s\n  namespace: monitoring\nspec:\n  retention: 30d\n  retentionSize: 90GiB\n  storage:\n    volumeClaimTemplate:\n      metadata:\n        labels:\n          app.kubernetes.io/component: prometheus\n          app.kubernetes.io/instance: k8s\n          app.kubernetes.io/name: prometheus\n          app.kubernetes.io/part-of: kube-prometheus\n        name: prometheus\n      spec:\n        accessModes:\n        - ReadWriteOnce\n        resources:\n          requests:\n            storage: 100Gi\n        storageClassName: premium-perf1-stackit\n"
  },
  {
    "path": "hack/config/monitoring/shoot/storageclass.yaml",
    "content": "apiVersion: storage.k8s.io/v1\nkind: StorageClass\nmetadata:\n  name: gce-ssd\nparameters:\n  type: pd-ssd\nallowVolumeExpansion: true\nprovisioner: pd.csi.storage.gke.io\nreclaimPolicy: Delete\nvolumeBindingMode: WaitForFirstConsumer\n"
  },
  {
    "path": "hack/config/monitoring/update.sh",
    "content": "#!/usr/bin/env bash\n\nset -o errexit\nset -o nounset\nset -o pipefail\n\ncd \"$(dirname \"${BASH_SOURCE[0]}\")\"\n\n# renovate: datasource=github-releases depName=prometheus-operator/kube-prometheus\nKUBE_PROMETHEUS_VERSION=v0.16.0\necho \"> Fetching kube-prometheus@$KUBE_PROMETHEUS_VERSION\"\n\ntmp_dir=$(mktemp -d)\ntrap 'rm -rf \"$tmp_dir\"' EXIT\n\ntarball=\"$tmp_dir/archive.tar.gz\"\ncurl -sSLo \"$tarball\" https://github.com/prometheus-operator/kube-prometheus/archive/refs/tags/$KUBE_PROMETHEUS_VERSION.tar.gz\n\nprometheus_operator_version=$(tar -xzf \"$tarball\" --wildcards \"kube-prometheus-*/manifests/prometheusOperator-deployment.yaml\" -O | grep app.kubernetes.io/version | head -1 | awk '{print $2}')\necho \"Included prometheus-operator version: $prometheus_operator_version\"\n\necho \"> Updating CRDs\"\npushd crds >/dev/null\nrm *.yaml\n\ntar -xzf \"$tarball\" --strip-components=3 --wildcards \"kube-prometheus-*/manifests/setup/*.yaml\"\n\n# drop unneeded stuff\nrm namespace.yaml\n\ncat <<EOF > README.md\nThe CRDs in this directory were downloaded from\nhttps://github.com/prometheus-operator/kube-prometheus/tree/$KUBE_PROMETHEUS_VERSION/manifests/setup.\n\nBump the version in [\\`$(basename $0)\\`](../$(basename $0)) and run the script to update the CRDs.\nEOF\n\ncat <<EOF > kustomization.yaml\n# Code generated by $(basename $0), DO NOT EDIT.\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nlabels:\n- includeSelectors: true\n  pairs:\n    app.kubernetes.io/name: prometheus-operator\n    app.kubernetes.io/part-of: kube-prometheus\n    app.kubernetes.io/version: $prometheus_operator_version\n\nresources:\n$(ls *.yaml | sed 's/^/- /')\nEOF\n\npopd >/dev/null\n\necho \"> Updating kube-prometheus\"\npushd kube-prometheus >/dev/null\nrm *.yaml\n\ntar -xzf \"$tarball\" --strip-components=2 --wildcards \"kube-prometheus-*/manifests/*.yaml\"\n\n# drop unneeded stuff\nrm -rf setup\nrm alertmanager-*.yaml\n# this will override metrics-server APIService (conflicts with gardener-resource-manager), drop it\nrm prometheusAdapter-apiService.yaml\n# PDB with minAvailable=1 for a single-replica StatefulSet blocks rolling node upgrades forever\nrm prometheus-podDisruptionBudget.yaml\n\ncat <<EOF > README.md\nThe manifests in this directory were downloaded from\nhttps://github.com/prometheus-operator/kube-prometheus/tree/$KUBE_PROMETHEUS_VERSION/manifests.\n\nBump the version in [\\`$(basename $0)\\`](../$(basename $0)) and run the script to update the CRDs.\nEOF\n\ncat <<EOF > kustomization.yaml\n# Code generated by $(basename $0), DO NOT EDIT.\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n$(ls *.yaml | sed 's/^/- /')\nEOF\n\npopd >/dev/null\n"
  },
  {
    "path": "hack/config/policy/ci/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- no-requests.yaml\n"
  },
  {
    "path": "hack/config/policy/ci/no-requests.yaml",
    "content": "apiVersion: kyverno.io/v1\nkind: ClusterPolicy\nmetadata:\n  name: no-requests-limits\nspec:\n  failurePolicy: Fail\n  rules:\n  # drop resource requests to allow scheduling all controller instances on a resource-restricted kind cluster (e.g., in CI)\n  - name: no-requests-limits\n    match:\n      any:\n      - resources:\n          kinds:\n          - Pod\n          selector:\n            matchExpressions:\n            - key: app.kubernetes.io/name\n              operator: In\n              values:\n              - controller-sharding\n            - key: app.kubernetes.io/component\n              operator: In\n              values:\n              - sharder\n              - checksum-controller\n          operations:\n          - CREATE\n      - resources:\n          kinds:\n          - Pod\n          selector:\n            matchExpressions:\n            - key: app.kubernetes.io/name\n              operator: In\n              values:\n              - webhosting-operator\n          operations:\n          - CREATE\n    mutate:\n      foreach:\n      - list: request.object.spec.containers\n        patchStrategicMerge:\n          spec:\n            containers:\n            - (name): \"{{element.name}}\"\n              resources: null\n"
  },
  {
    "path": "hack/config/policy/controlplane/etcd-main.yaml",
    "content": "apiVersion: kyverno.io/v1\nkind: Policy\nmetadata:\n  name: etcd-main\n  namespace: shoot--ixywdlfvei--sharding\nspec:\n  failurePolicy: Fail\n  rules:\n  # set static requests/limits on etcd-main to ensure similar evaluation environment between load test runs\n  - name: resources\n    match:\n      any:\n      - resources:\n          kinds:\n          - Pod\n          selector:\n            matchLabels:\n              app.kubernetes.io/name: etcd-main\n    mutate:\n      patchStrategicMerge:\n        spec:\n          containers:\n          - name: etcd\n            resources:\n              requests:\n                cpu: 12000m\n                memory: 12Gi\n              limits:\n                cpu: 12000m\n                memory: 12Gi\n            # set GOMAXPROCS to CPU quota to minimize goroutine scheduling contention (CPU throttling)\n            env:\n            - name: GOMAXPROCS\n              value: \"12\"\n  - name: disable-vpa\n    match:\n      any:\n      - resources:\n          kinds:\n          - VerticalPodAutoscaler\n          names:\n          - etcd-main\n    mutate:\n      patchStrategicMerge:\n        spec:\n          updatePolicy:\n            updateMode: Off\n"
  },
  {
    "path": "hack/config/policy/controlplane/kube-apiserver.yaml",
    "content": "apiVersion: kyverno.io/v1\nkind: Policy\nmetadata:\n  name: kube-apiserver\n  namespace: shoot--ixywdlfvei--sharding\nspec:\n  failurePolicy: Fail\n  rules:\n  # set static replicas on kube-apiserver to ensure similar evaluation environment between load test runs\n  - name: disable-hpa\n    match:\n      any:\n      - resources:\n          kinds:\n          - HorizontalPodAutoscaler\n          names:\n          - kube-apiserver\n    mutate:\n      patchStrategicMerge:\n        spec:\n          minReplicas: 4\n          maxReplicas: 4\n  # set static requests/limits on kube-apiserver to ensure similar evaluation environment between load test runs\n  - name: resources\n    match:\n      any:\n      - resources:\n          kinds:\n          - Pod\n          selector:\n            matchLabels:\n              app: kubernetes\n              role: apiserver\n    mutate:\n      patchStrategicMerge:\n        spec:\n          containers:\n          - name: kube-apiserver\n            resources:\n              requests:\n                cpu: 12000m\n                memory: 12Gi\n              limits:\n                cpu: 12000m\n                memory: 12Gi\n            # set GOMAXPROCS to CPU quota to minimize goroutine scheduling contention (CPU throttling)\n            env:\n            - name: GOMAXPROCS\n              value: \"12\"\n  - name: disable-vpa\n    match:\n      any:\n      - resources:\n          kinds:\n          - VerticalPodAutoscaler\n          names:\n          - kube-apiserver-vpa\n    mutate:\n      patchStrategicMerge:\n        spec:\n          updatePolicy:\n            updateMode: Off\n"
  },
  {
    "path": "hack/config/policy/controlplane/kube-controller-manager.yaml",
    "content": "apiVersion: kyverno.io/v1\nkind: Policy\nmetadata:\n  name: kube-controller-manager\n  namespace: shoot--ixywdlfvei--sharding\nspec:\n  failurePolicy: Ignore\n  rules:\n  # set static requests/limits on kube-controller-manager to ensure similar evaluation environment between load test runs\n  - name: resources\n    match:\n      any:\n      - resources:\n          kinds:\n          - Pod\n          selector:\n            matchLabels:\n              app: kubernetes\n              role: controller-manager\n    mutate:\n      patchStrategicMerge:\n        spec:\n          containers:\n          - name: kube-controller-manager\n            resources:\n              requests:\n                cpu: 6000m\n                memory: 6Gi\n              limits:\n                cpu: 6000m\n                memory: 6Gi\n            # set GOMAXPROCS to CPU quota to minimize goroutine scheduling contention (CPU throttling)\n            env:\n            - name: GOMAXPROCS\n              value: \"6\"\n  - name: disable-vpa\n    match:\n      any:\n      - resources:\n          kinds:\n          - VerticalPodAutoscaler\n          names:\n          - kube-controller-manager-vpa\n    mutate:\n      patchStrategicMerge:\n        spec:\n          updatePolicy:\n            updateMode: Off\n  # disable kube-controller-manager's client-side rate limits similar to webhosting-operator\n  - name: disable-rate-limits\n    match:\n      any:\n      - resources:\n          kinds:\n          - Deployment\n          names:\n          - kube-controller-manager\n    mutate:\n      patchesJson6902: |-\n        - op: add\n          path: /spec/template/spec/containers/0/command/-\n          value: \"--kube-api-qps=-1\"\n  # disable HTTP2 in kube-controller-manager's so that API requests are distributed across API server instances\n  - name: disable-http2\n    match:\n      any:\n      - resources:\n          kinds:\n          - Deployment\n          names:\n          - kube-controller-manager\n    mutate:\n      patchStrategicMerge:\n        spec:\n          template:\n            spec:\n              containers:\n              - name: kube-controller-manager\n                env:\n                - name: DISABLE_HTTP2\n                  value: \"true\"\n"
  },
  {
    "path": "hack/config/policy/controlplane/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\n# This kustomization contains policies for manipulating shoot control plane components.\n# For this to work, kyverno needs to be installed on the seed cluster.\n\nresources:\n- etcd-main.yaml\n- kube-apiserver.yaml\n- kube-controller-manager.yaml\n"
  },
  {
    "path": "hack/config/policy/shoot/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- sharder-scheduling.yaml\n"
  },
  {
    "path": "hack/config/policy/shoot/sharder-scheduling.yaml",
    "content": "apiVersion: kyverno.io/v1\nkind: ClusterPolicy\nmetadata:\n  name: sharder-scheduling\nspec:\n  failurePolicy: Fail\n  rules:\n  # schedule sharder on dedicated worker pool for better isolation in load tests\n  - name: add-scheduling-constraints\n    match:\n      any:\n      - resources:\n          kinds:\n          - Pod\n          namespaces:\n          - sharding-system\n          selector:\n            matchLabels:\n              app.kubernetes.io/name: controller-sharding\n              app.kubernetes.io/component: sharder\n          operations:\n          - CREATE\n    mutate:\n      patchesJson6902: |-\n        - op: add\n          path: \"/spec/tolerations/-\"\n          value: {\"key\":\"dedicated-for\",\"operator\":\"Equal\",\"value\":\"sharding\",\"effect\":\"NoSchedule\"}        \n        - op: add\n          path: \"/spec/affinity/nodeAffinity/requiredDuringSchedulingIgnoredDuringExecution/nodeSelectorTerms/-\"\n          value: {\"matchExpressions\": [{\"key\":\"dedicated-for\",\"operator\":\"In\",\"values\":[\"sharding\"]}]}        \n"
  },
  {
    "path": "hack/config/profiling/ensure-admin-password.sh",
    "content": "#!/usr/bin/env bash\n\ndir=\"$(dirname \"$0\")\"\npassword_file=\"$dir/parca_password.secret.txt\"\nauth_file=\"$dir/parca_auth.secret.txt\"\n\n[ -f \"$password_file\" ] && [ -f \"$auth_file\" ] && exit 0\ncat /dev/urandom | tr -dc \"a-zA-Z0-9\" | head -c 32 > \"$password_file\"\ncat \"$password_file\" | htpasswd -i -c \"$auth_file\" parca\n"
  },
  {
    "path": "hack/config/profiling/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- https://github.com/parca-dev/parca/releases/download/v0.24.2/kubernetes-manifest.yaml\n- parca_ingress.yaml\n- parca_pvc.yaml\n# grant parca running in namespace \"parca\" permissions required for service discovery in namespace\n# \"sharding-system\" and scrape the pprof endpoints of sharder\n- rbac_sharder.yaml\n\ngeneratorOptions:\n  disableNameSuffixHash: true\n  labels:\n    app.kubernetes.io/component: observability\n    app.kubernetes.io/instance: parca\n    app.kubernetes.io/name: parca\n\nconfigMapGenerator:\n- name: parca\n  namespace: parca\n  behavior: merge\n  files:\n  - parca.yaml=parca_config.yaml\n\nsecretGenerator:\n- name: parca-basic-auth\n  namespace: parca\n  literals:\n  - username=parca\n  files:\n  - password=parca_password.secret.txt\n  - auth=parca_auth.secret.txt\n\npatches:\n- path: patch_deployment_pvc.yaml\n- target:\n    kind: Deployment\n    name: parca\n    namespace: parca\n  patch: |\n    - op: add\n      path: /spec/template/spec/containers/0/args/-\n      value: --enable-persistence\n    - op: add\n      path: /spec/template/spec/containers/0/args/-\n      value: --storage-path=/var/lib/parca\n    - op: add\n      path: /spec/template/spec/containers/0/args/-\n      value: --storage-enable-wal\n"
  },
  {
    "path": "hack/config/profiling/parca_config.yaml",
    "content": "object_storage:\n  bucket:\n    config:\n      directory: /var/lib/parca\n    type: FILESYSTEM\n\nscrape_configs:\n# heavily inspired by the prometheus scrape config generated by prometheus-operator for sharder ServiceMonitor\n- job_name: sharder\n  scrape_interval: 2s\n  scrape_timeout: 4s\n  scheme: https\n  authorization:\n    type: Bearer\n    credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token\n  tls_config:\n    insecure_skip_verify: true\n  kubernetes_sd_configs:\n  - role: endpoints\n    namespaces:\n      names:\n      - sharding-system\n  relabel_configs:\n  - action: keep\n    source_labels:\n    - __meta_kubernetes_service_label_app_kubernetes_io_name\n    - __meta_kubernetes_service_labelpresent_app_kubernetes_io_name\n    regex: (controller-sharding);true\n  - action: keep\n    source_labels:\n    - __meta_kubernetes_service_label_app_kubernetes_io_component\n    - __meta_kubernetes_service_labelpresent_app_kubernetes_io_component\n    regex: (sharder);true\n  - action: keep\n    source_labels:\n    - __meta_kubernetes_endpoint_port_name\n    regex: metrics\n  - source_labels:\n    - __meta_kubernetes_endpoint_address_target_kind\n    - __meta_kubernetes_endpoint_address_target_name\n    separator: ;\n    regex: Node;(.*)\n    replacement: ${1}\n    target_label: node\n  - source_labels:\n    - __meta_kubernetes_endpoint_address_target_kind\n    - __meta_kubernetes_endpoint_address_target_name\n    separator: ;\n    regex: Pod;(.*)\n    replacement: ${1}\n    target_label: pod\n  - source_labels:\n    - __meta_kubernetes_namespace\n    target_label: namespace\n  - source_labels:\n    - __meta_kubernetes_service_name\n    target_label: service\n  - source_labels:\n    - __meta_kubernetes_pod_name\n    target_label: pod\n  - source_labels:\n    - __meta_kubernetes_pod_container_name\n    target_label: container\n  - source_labels:\n    - __meta_kubernetes_service_name\n    target_label: job\n    replacement: ${1}\n  - target_label: endpoint\n    replacement: metrics\n  - target_label: job\n    replacement: sharder\n    action: replace\n# heavily inspired by the prometheus scrape config generated by prometheus-operator for webhosting-operator ServiceMonitor\n- job_name: webhosting-operator\n  scrape_interval: 2s\n  scrape_timeout: 4s\n  scheme: https\n  authorization:\n    type: Bearer\n    credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token\n  tls_config:\n    insecure_skip_verify: true\n  kubernetes_sd_configs:\n  - role: endpoints\n    namespaces:\n      names:\n      - webhosting-system\n  relabel_configs:\n  - action: keep\n    source_labels:\n    - __meta_kubernetes_service_label_app_kubernetes_io_name\n    - __meta_kubernetes_service_labelpresent_app_kubernetes_io_name\n    regex: (webhosting-operator);true\n  - action: keep\n    source_labels:\n    - __meta_kubernetes_endpoint_port_name\n    regex: https\n  - source_labels:\n    - __meta_kubernetes_endpoint_address_target_kind\n    - __meta_kubernetes_endpoint_address_target_name\n    separator: ;\n    regex: Node;(.*)\n    replacement: ${1}\n    target_label: node\n  - source_labels:\n    - __meta_kubernetes_endpoint_address_target_kind\n    - __meta_kubernetes_endpoint_address_target_name\n    separator: ;\n    regex: Pod;(.*)\n    replacement: ${1}\n    target_label: pod\n  - source_labels:\n    - __meta_kubernetes_namespace\n    target_label: namespace\n  - source_labels:\n    - __meta_kubernetes_service_name\n    target_label: service\n  - source_labels:\n    - __meta_kubernetes_pod_name\n    target_label: pod\n  - source_labels:\n    - __meta_kubernetes_pod_container_name\n    target_label: container\n  - source_labels:\n    - __meta_kubernetes_service_name\n    target_label: job\n    replacement: ${1}\n  - target_label: endpoint\n    replacement: https\n  - target_label: job\n    replacement: webhosting-operator\n    action: replace\n"
  },
  {
    "path": "hack/config/profiling/parca_ingress.yaml",
    "content": "apiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n  annotations:\n    cert-manager.io/cluster-issuer: letsencrypt-http01\n    nginx.ingress.kubernetes.io/auth-type: basic\n    nginx.ingress.kubernetes.io/auth-secret: parca-basic-auth\n    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'\n  labels:\n    app.kubernetes.io/component: observability\n    app.kubernetes.io/instance: parca\n    app.kubernetes.io/name: parca\n  name: parca\n  namespace: parca\nspec:\n  ingressClassName: nginx\n  rules:\n  - host: parca.webhosting.timebertt.dev\n    http:\n      paths:\n      - backend:\n          service:\n            name: parca\n            port:\n              name: http\n        path: /\n        pathType: Prefix\n  tls:\n  - hosts:\n    - parca.webhosting.timebertt.dev\n    secretName: parca-tls\n"
  },
  {
    "path": "hack/config/profiling/parca_pvc.yaml",
    "content": "apiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  labels:\n    app.kubernetes.io/component: observability\n    app.kubernetes.io/instance: parca\n    app.kubernetes.io/name: parca\n  name: parca\n  namespace: parca\nspec:\n  accessModes:\n  - ReadWriteOnce\n  resources:\n    requests:\n      storage: 150Gi\n"
  },
  {
    "path": "hack/config/profiling/patch_deployment_pvc.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: parca\n  namespace: parca\nspec:\n  # set replicas and strategy to play nicely with PVC\n  replicas: 1\n  strategy:\n    type: Recreate\n    rollingUpdate: null\n  template:\n    spec:\n      volumes:\n      - name: data\n        emptyDir: null\n        persistentVolumeClaim:\n          claimName: parca\n"
  },
  {
    "path": "hack/config/profiling/rbac_sharder.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  name: parca-service-discovery\n  namespace: sharding-system\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - services\n  - endpoints\n  - pods\n  verbs:\n  - get\n  - list\n  - watch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: parca-service-discovery\n  namespace: sharding-system\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: parca-service-discovery\nsubjects:\n- kind: ServiceAccount\n  name: parca\n  namespace: parca\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: observability\n    app.kubernetes.io/instance: parca\n    app.kubernetes.io/name: parca\n  name: parca-sharder-pprof-reader\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: sharding:sharder:pprof-reader\nsubjects:\n- kind: ServiceAccount\n  name: parca\n  namespace: parca\n"
  },
  {
    "path": "hack/config/sharder/devel/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../../../../config/default\n\npatches:\n- target:\n    group: apps\n    kind: Deployment\n    name: sharder\n    namespace: sharding-system\n  patch: |\n    - op: add\n      path: /spec/template/spec/containers/0/args/-\n      value: --zap-devel\n"
  },
  {
    "path": "hack/config/sharder/host/config.yaml",
    "content": "apiVersion: config.sharding.timebertt.dev/v1alpha1\nkind: SharderConfig\nwebhook:\n  server:\n    certDir: hack/config/certificates/host\n    certName: webhook-server.pem\n    keyName: webhook-server-key.pem\n  config:\n    annotations:\n      cert-manager.io/inject-ca-from-secret: sharding-system/webhook-ca\n    clientConfig:\n      url: https://host.docker.internal:9443/\ncontroller:\n  sharder:\n    syncPeriod: 30s\n"
  },
  {
    "path": "hack/config/shoot.yaml",
    "content": "apiVersion: core.gardener.cloud/v1beta1\nkind: Shoot\nmetadata:\n  name: sharding\n  namespace: garden-ixywdlfvei-ccknp\nspec:\n  addons:\n    kubernetesDashboard:\n      enabled: false\n  cloudProfile:\n    kind: CloudProfile\n    name: stackit\n  cloudProfileName: stackit\n  controlPlane:\n    highAvailability:\n      failureTolerance:\n        type: zone\n  credentialsBindingName: ixywdlfvei-infrastructure\n  hibernation:\n    schedules:\n    - location: Europe/Berlin\n      start: 0 5 * * *\n  kubernetes:\n    kubeAPIServer:\n      requests:\n        maxMutatingInflight: 200\n        maxNonMutatingInflight: 400\n    kubeControllerManager:\n      nodeCIDRMaskSize: 24\n    kubeProxy:\n      mode: IPTables\n    kubelet:\n      serializeImagePulls: false\n    version: \"1.33\"\n  maintenance:\n    autoUpdate:\n      kubernetesVersion: true\n      machineImageVersion: true\n    timeWindow:\n      begin: 030000+0200\n      end: 040000+0200\n  networking:\n    ipFamilies:\n    - IPv4\n    nodes: 10.250.0.0/16\n    pods: 100.64.0.0/13\n    services: 100.82.0.0/16\n    providerConfig:\n      apiVersion: calico.networking.extensions.gardener.cloud/v1alpha1\n      kind: NetworkConfig\n      backend: bird\n      ipv4:\n        mode: Always\n        pool: ipip\n    type: calico\n  provider:\n    controlPlaneConfig:\n      apiVersion: stackit.provider.extensions.gardener.cloud/v1alpha1\n      kind: ControlPlaneConfig\n    infrastructureConfig:\n      apiVersion: stackit.provider.extensions.gardener.cloud/v1alpha1\n      kind: InfrastructureConfig\n      floatingPoolName: floating-net\n      networks:\n        workers: 10.250.0.0/16\n    type: stackit\n    workers:\n    # runs system and monitoring components (default worker pool)\n    - name: system\n      cri:\n        name: containerd\n      machine:\n        architecture: amd64\n        image:\n          name: coreos\n        type: g1a.8d\n      maxSurge: 1\n      maxUnavailable: 0\n      maximum: 2\n      minimum: 1\n      systemComponents:\n        allow: true\n      volume:\n        size: 50Gi\n        type: storage_premium_perf1\n      zones:\n      - eu01-3\n    # runs sharding components and webhosting-operator\n    - name: sharding\n      cri:\n        name: containerd\n      labels:\n        dedicated-for: sharding\n      machine:\n        architecture: amd64\n        image:\n          name: coreos\n        type: g1a.8d\n      maxSurge: 1\n      maxUnavailable: 0\n      maximum: 3\n      minimum: 2\n      systemComponents:\n        allow: false\n      taints:\n      - effect: NoSchedule\n        key: dedicated-for\n        value: sharding\n      volume:\n        size: 50Gi\n        type: storage_premium_perf1\n      zones:\n      - eu01-3\n    # runs experiment (optional)\n    - name: experiment\n      cri:\n        name: containerd\n      labels:\n        dedicated-for: experiment\n      machine:\n        architecture: amd64\n        image:\n          name: coreos\n        type: g1a.8d\n      maxSurge: 1\n      maxUnavailable: 0\n      maximum: 1\n      minimum: 0\n      systemComponents:\n        allow: false\n      taints:\n      - effect: NoSchedule\n        key: dedicated-for\n        value: experiment\n      volume:\n        size: 50Gi\n        type: storage_premium_perf1\n      zones:\n      - eu01-3\n  purpose: production\n  region: RegionOne\n"
  },
  {
    "path": "hack/config/skaffold.yaml",
    "content": "apiVersion: skaffold/v4beta13\nkind: Config\nmetadata:\n  name: cert-manager\nmanifests:\n  kustomize:\n    paths:\n      - hack/config/cert-manager\ndeploy:\n  kubectl:\n    flags:\n      apply:\n        - --server-side\n        - --force-conflicts\n    defaultNamespace: \"\"\n    hooks:\n      after:\n        - host:\n            command:\n              - /usr/bin/env\n              - bash\n              - -c\n              - |\n                for i in $(seq 1 20); do\n                  if [ \"$(kubectl get validatingwebhookconfiguration cert-manager-webhook -oyaml 2>/dev/null | yq '.webhooks[].clientConfig.caBundle')\" != \"null\" ] ; then\n                    exit 0\n                  fi\n                  echo \"Waiting until CA has been injected into cert-manager webhook\"\n                  sleep 5\n                done\n                exit 1\n---\napiVersion: skaffold/v4beta13\nkind: Config\nmetadata:\n  name: cert-manager-resources\nmanifests:\n  kustomize:\n    paths:\n      - hack/config/cert-manager/resources\ndeploy:\n  kubectl:\n    flags:\n      apply:\n        - --server-side\n        - --force-conflicts\n    defaultNamespace: \"\"\n---\napiVersion: skaffold/v4beta13\nkind: Config\nmetadata:\n  name: ingress-nginx\nmanifests:\n  kustomize:\n    paths:\n      - hack/config/ingress-nginx/default\ndeploy:\n  kubectl:\n    flags:\n      apply:\n        - --server-side\n        - --force-conflicts\n    defaultNamespace: \"\"\n    hooks:\n      before:\n        - host:\n            command:\n              - /usr/bin/env\n              - bash\n              - -c\n              # job template is immutable, delete the old job to prepare for upgrade\n              - kubectl -n ingress-nginx delete job --ignore-not-found ingress-nginx-admission-create ingress-nginx-admission-patch\nprofiles:\n  - name: kind\n    activation:\n      - kubeContext: kind-.*\n    manifests:\n      kustomize:\n        paths:\n          - hack/config/ingress-nginx/kind\n  - name: shoot\n    activation:\n      - kubeContext: .*--sharding.*\n    manifests:\n      kustomize:\n        paths:\n          - hack/config/ingress-nginx/shoot\n---\napiVersion: skaffold/v4beta13\nkind: Config\nmetadata:\n  name: kyverno\nmanifests:\n  kustomize:\n    paths:\n      - hack/config/kyverno\ndeploy:\n  kubectl:\n    flags:\n      apply:\n        - --server-side\n        - --force-conflicts\n    defaultNamespace: \"\"\n    hooks:\n      after:\n        - host:\n            command:\n              - /usr/bin/env\n              - bash\n              - -c\n              - |\n                kubectl wait --for=condition=Available=true deploy -n kyverno kyverno-admission-controller --timeout=120s\n                kubectl wait --for=create validatingwebhookconfiguration kyverno-policy-validating-webhook-cfg\n                kubectl wait --for=create mutatingwebhookconfiguration kyverno-resource-mutating-webhook-cfg\n\n                for i in $(seq 1 20); do\n                  # create dummy policy with dry-run enabled to test availability of webhook\n                  if kubectl create --dry-run=server -f <(yq '.metadata.name |= \"test-kyverno\"' hack/config/policy/shoot/sharder-scheduling.yaml) ; then\n                    exit 0\n                  fi\n                  echo \"Waiting until kyverno webhook is ready to handle policy creation\"\n                  sleep 5\n                done\n                exit 1\n---\napiVersion: skaffold/v4beta13\nkind: Config\nmetadata:\n  name: policy\nrequires:\n  - configs:\n      - kyverno\nprofiles:\n  - name: shoot\n    activation:\n      - kubeContext: .*--sharding.*\n    manifests:\n      kustomize:\n        paths:\n          - hack/config/policy/shoot\n    deploy:\n      kubectl:\n        flags:\n          apply:\n            - --server-side\n            - --force-conflicts\n        defaultNamespace: \"\"\n  - name: ci\n    activation:\n      - env: CI=.+\n    manifests:\n      kustomize:\n        paths:\n          - hack/config/policy/ci\n    deploy:\n      kubectl:\n        flags:\n          apply:\n            - --server-side\n            - --force-conflicts\n        defaultNamespace: \"\"\n        hooks:\n          after:\n            - host:\n                command:\n                  - /usr/bin/env\n                  - bash\n                  - -c\n                  - kubectl wait --for=condition=Ready=true clusterpolicy no-requests-limits --timeout=30s\n---\napiVersion: skaffold/v4beta13\nkind: Config\nmetadata:\n  name: sharder\nbuild:\n  artifacts:\n    - image: ghcr.io/timebertt/kubernetes-controller-sharding/sharder\n      ko:\n        dependencies:\n          paths:\n            - go.mod\n            - cmd/**/*.go\n            - pkg/**/*.go\n        main: ./cmd/sharder\n  tagPolicy:\n    inputDigest: {}\n  local:\n    concurrency: 0\nmanifests:\n  kustomize:\n    paths:\n      - config/default\n  hooks:\n    before:\n      - host:\n          # ensure deepcopy, CRDs, and RBAC are up-to-date\n          command:\n            - make\n            - generate-fast\ndeploy:\n  kubectl:\n    flags:\n      apply:\n        - --server-side\n        - --force-conflicts\n    defaultNamespace: \"\"\nprofiles:\n  - name: devel\n    activation:\n      - kubeContext: kind-.*\n      - env: DEVEL=true\n    patches:\n      - op: replace\n        path: /manifests/kustomize/paths/0\n        value: hack/config/sharder/devel\n---\napiVersion: skaffold/v4beta13\nkind: Config\nmetadata:\n  name: checksum-controller\nbuild:\n  artifacts:\n    - image: ghcr.io/timebertt/kubernetes-controller-sharding/checksum-controller\n      ko:\n        dependencies:\n          paths:\n            - go.mod\n            - cmd/**/*.go\n            - pkg/**/*.go\n        main: ./cmd/checksum-controller\n  tagPolicy:\n    inputDigest: {}\n  local:\n    concurrency: 0\nmanifests:\n  kustomize:\n    paths:\n      - hack/config/checksum-controller/controller\ndeploy:\n  kubectl:\n    flags:\n      apply:\n        - --server-side\n        - --force-conflicts\n    defaultNamespace: \"\"\n---\napiVersion: skaffold/v4beta13\nkind: Config\nmetadata:\n  name: monitoring-crds\nmanifests:\n  kustomize:\n    paths:\n      - hack/config/monitoring/crds\ndeploy:\n  kubectl:\n    flags:\n      apply:\n        - --server-side\n        - --force-conflicts\n    defaultNamespace: \"\"\n---\napiVersion: skaffold/v4beta13\nkind: Config\nmetadata:\n  name: monitoring\nrequires:\n  - configs:\n      - monitoring-crds\nmanifests:\n  kustomize:\n    paths:\n      - hack/config/monitoring/default\n      - config/monitoring\n  hooks:\n    before:\n      - host:\n          command:\n            - hack/config/monitoring/default/ensure-admin-password.sh\ndeploy:\n  kubectl:\n    flags:\n      apply:\n        - --server-side\n        - --force-conflicts\n    defaultNamespace: \"\"\nportForward:\n  - resourceType: service\n    resourceName: grafana\n    namespace: monitoring\n    port: http\n    localPort: 3001\n  - resourceType: service\n    resourceName: prometheus-k8s\n    namespace: monitoring\n    port: web\n    localPort: 9091\nprofiles:\n  - name: shoot\n    activation:\n      - kubeContext: .*--sharding.*\n    patches:\n      - op: replace\n        path: /manifests/kustomize/paths/0\n        value: hack/config/monitoring/shoot\n---\napiVersion: skaffold/v4beta13\nkind: Config\nmetadata:\n  name: profiling\nprofiles:\n  - name: profiling\n    manifests:\n      kustomize:\n        paths:\n          - hack/config/profiling\n      hooks:\n        before:\n          - host:\n              command:\n                - hack/config/profiling/ensure-admin-password.sh\n    deploy:\n      kubectl:\n        flags:\n          apply:\n            - --server-side\n            - --force-conflicts\n        defaultNamespace: \"\"\n    portForward:\n      - resourceType: service\n        resourceName: parca\n        namespace: parca\n        port: http\n        localPort: 7071\n---\napiVersion: skaffold/v4beta13\nkind: Config\nmetadata:\n  name: webhosting-operator\nbuild:\n  artifacts:\n    - image: ghcr.io/timebertt/kubernetes-controller-sharding/webhosting-operator\n      ko:\n        dependencies:\n          paths:\n            - go.mod\n            - webhosting-operator/go.mod\n            - pkg/**/*.go\n            - webhosting-operator/**/*.go\n        main: ./webhosting-operator/cmd/webhosting-operator\n  tagPolicy:\n    inputDigest: {}\n  local:\n    concurrency: 0\nmanifests:\n  kustomize:\n    paths:\n      # default configuration: only run operator shards and use external sharding implementation via ControllerRing\n      - webhosting-operator/config/manager/overlays/default\n      - webhosting-operator/config/monitoring/default\ndeploy:\n  kubectl:\n    flags:\n      apply:\n        - --server-side\n        - --force-conflicts\n    defaultNamespace: \"\"\n    hooks:\n      before:\n        - host:\n            # ensure CRDs and RBAC are up-to-date\n            command:\n              - make\n              - generate-fast-webhosting\nprofiles:\n  - name: devel\n    activation:\n      - kubeContext: kind-.*\n      - env: DEVEL=true\n    patches:\n      - op: replace\n        path: /manifests/kustomize/paths/0\n        value: webhosting-operator/config/manager/overlays/devel\n  - name: debug\n    activation:\n      - command: debug\n    patches:\n      - op: replace\n        path: /manifests/kustomize/paths/0\n        value: webhosting-operator/config/manager/overlays/debug\n  - name: non-sharded\n    activation:\n      - env: ENABLE_SHARDING=false\n    patches:\n      - op: replace\n        path: /manifests/kustomize/paths/0\n        # singleton controller without sharding for comparison\n        value: webhosting-operator/config/manager/overlays/non-sharded\n  - name: non-sharded-devel\n    activation:\n      - env: ENABLE_SHARDING=false\n      - env: DEVEL=true\n    requiresAllActivations: true\n    patches:\n      - op: replace\n        path: /manifests/kustomize/paths/0\n        value: webhosting-operator/config/manager/overlays/non-sharded-devel\n  # The following profiles are variants of the default and non-sharded profiles for running on the shoot cluster\n  # with dns for websites enabled.\n  - name: shoot\n    activation:\n      - kubeContext: .*--sharding.*\n    patches:\n      - op: replace\n        path: /manifests/kustomize/paths/0\n        # default configuration: run sharded operator and use external sharding implementation via ControllerRing\n        value: webhosting-operator/config/manager/overlays/shoot/default\n      - op: add\n        path: /manifests/kustomize/paths/-\n        value: webhosting-operator/config/policy\n  - name: shoot-devel\n    activation:\n      - kubeContext: .*--sharding.*\n      - env: DEVEL=true\n    requiresAllActivations: true\n    patches:\n      - op: replace\n        path: /manifests/kustomize/paths/0\n        # default configuration + devel mode\n        value: webhosting-operator/config/manager/overlays/shoot/devel\n  - name: shoot-non-sharded\n    activation:\n      - kubeContext: .*--sharding.*\n      - env: ENABLE_SHARDING=false\n    requiresAllActivations: true\n    patches:\n      - op: replace\n        path: /manifests/kustomize/paths/0\n        # singleton controller without sharding for comparison\n        value: webhosting-operator/config/manager/overlays/shoot/non-sharded\n  - name: shoot-non-sharded-devel\n    activation:\n      - kubeContext: .*--sharding.*\n      - env: ENABLE_SHARDING=false\n      - env: DEVEL=true\n    requiresAllActivations: true\n    patches:\n      - op: replace\n        path: /manifests/kustomize/paths/0\n        # non-sharded configuration + devel mode\n        value: webhosting-operator/config/manager/overlays/shoot/non-sharded-devel\n---\napiVersion: skaffold/v4beta13\nkind: Config\nmetadata:\n  name: experiment\nprofiles:\n  - name: expirement\n    activation:\n      - env: EXPERIMENT_SCENARIO=.+\n    build:\n      artifacts:\n        - image: ghcr.io/timebertt/kubernetes-controller-sharding/experiment\n          ko:\n            dependencies:\n              paths:\n                - go.mod\n                - webhosting-operator/go.mod\n                - pkg/**/*.go\n                - webhosting-operator/**/*.go\n            main: ./webhosting-operator/cmd/experiment\n      tagPolicy:\n        inputDigest: {}\n      local:\n        concurrency: 0\n    manifests:\n      kustomize:\n        paths:\n          - webhosting-operator/config/experiment/{{ .EXPERIMENT_SCENARIO }}\n    deploy:\n      kubectl:\n        flags:\n          apply:\n            - --server-side\n            - --force-conflicts\n        defaultNamespace: \"\"\n        hooks:\n          before:\n            - host:\n                command:\n                  - /usr/bin/env\n                  - bash\n                  - -c\n                  - |\n                    active_pods=\"$(kubectl -n experiment get job experiment -ojsonpath='{.status.active}' 2>/dev/null)\"\n                    if [ \"${active_pods:-0}\" -gt 0 ] && [ -z \"$EXPERIMENT_DELETE_FORCE\" ] ; then\n                      echo \"Experiment is running currently, refusing to delete the job. Set EXPERIMENT_DELETE_FORCE to override.\"\n                      exit 1\n                    fi\n                    kubectl -n experiment delete job experiment --ignore-not-found --wait=true\n            - host:\n                command:\n                  - /usr/bin/env\n                  - bash\n                  - -c\n                  - |\n                    if kubectl get controllerring checksum-controller &>/dev/null || kubectl -n default get deploy checksum-controller &>/dev/null ; then\n                      echo \"checksum-controller is still running, refusing to run a load test experiment.\"\n                      echo \"Ensure a clean load test environment, i.e., run 'make down SKAFFOLD_MODULE=checksum-controller'.\"\n                      exit 1\n                    fi\n"
  },
  {
    "path": "hack/prepare-image-metadata.sh",
    "content": "#!/usr/bin/env bash\n\n# This script generates comma-separated tags and labels for image builds (similar to docker/metadata-action).\n# It writes its output to the github output variable file or env file. It can only be used in github actions.\n\nset -x\nset -o errexit\nset -o pipefail\nset -o nounset\n\nbuild_date=\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"\n# revision is the commit sha\nrevision=$GITHUB_SHA\n# short_ref is the branch name, or the semver git tag\nshort_ref=$GITHUB_REF_NAME\n# version is the semantic version\nversion=v0.1.0-dev # used if no semver tag has been pushed yet\nmajor_version=\"0\"\nminor_version=\"1\"\n\ntags=( \"sha-$( echo \"$revision\" | head -c7 )\" )\nif [[ $short_ref = main ]] ; then\n  tags+=( latest )\nfi\n\nif [[ $GITHUB_REF = refs/tags/* && $short_ref =~ ^v([0-9]+)\\.([0-9]+)\\.([0-9]+)([-].*)?([+].*)?$ ]] ; then\n  # triggered for a semver tag, add it as image tag\n  tags+=( \"$short_ref\" )\n\n  # extract version information\n  version=$short_ref\n\n  major_version=${BASH_REMATCH[1]}\n  minor_version=${BASH_REMATCH[2]}\nelif [[ \"$(git describe --tags --match \"v*.*.*\" --abbrev=0 2>/dev/null)\" =~ ^v([0-9]+)\\.([0-9]+)\\.([0-9]+)$ ]] ; then\n  # otherwise, find the previous semver tag, extract its information, bump minor/patch, and append -dev\n  major_version=${BASH_REMATCH[1]}\n  minor_version=${BASH_REMATCH[2]}\n  patch_version=${BASH_REMATCH[3]}\n\n  if [[ $short_ref = release-* ]] ; then\n    (( patch_version++ ))\n  else\n    (( minor_version++ ))\n  fi\n\n  version=v$major_version.$minor_version.$patch_version-dev\nfi\n\nlabels=(\n  org.opencontainers.image.created=\"$build_date\"\n  org.opencontainers.image.licenses=\"Apache-2.0\"\n  org.opencontainers.image.revision=\"$revision\"\n  org.opencontainers.image.source=\"https://github.com/$GITHUB_REPOSITORY\"\n  org.opencontainers.image.url=\"https://github.com/$GITHUB_REPOSITORY\"\n  org.opencontainers.image.version=\"$version\"\n)\n\necho \"tags=$(IFS=, ; echo \"${tags[*]}\")\" >> \"$GITHUB_OUTPUT\"\necho \"labels=$(IFS=, ; echo \"${labels[*]}\")\" >> \"$GITHUB_OUTPUT\"\n\n# calculate ldflags for injecting version information into binaries\ntree_state=\"$([[ -z \"$(git status --porcelain 2>/dev/null)\" ]] && echo clean || echo dirty)\"\n\n# passing multi-line strings through an action output is difficult, through env vars is easier\necho \"LDFLAGS<<EOF\n-X k8s.io/component-base/version.gitMajor=$major_version\n-X k8s.io/component-base/version.gitMinor=$minor_version\n-X k8s.io/component-base/version.gitVersion=$version\n-X k8s.io/component-base/version.gitTreeState=$tree_state\n-X k8s.io/component-base/version.gitCommit=$revision\n-X k8s.io/component-base/version.buildDate=$build_date\n-X k8s.io/component-base/version/verflag.programName=kubernetes-controller-sharding\nEOF\" >> \"$GITHUB_ENV\"\n"
  },
  {
    "path": "hack/test-e2e.env",
    "content": "export GOMEGA_DEFAULT_EVENTUALLY_TIMEOUT=5m\nexport GOMEGA_DEFAULT_EVENTUALLY_POLLING_INTERVAL=500ms\nexport GOMEGA_DEFAULT_CONSISTENTLY_DURATION=10s\nexport GOMEGA_DEFAULT_CONSISTENTLY_POLLING_INTERVAL=500ms\n"
  },
  {
    "path": "hack/test-e2e.sh",
    "content": "#!/usr/bin/env bash\n\nset -o nounset\nset -o pipefail\nset -o errexit\n\nsource \"$(dirname \"$0\")/test-e2e.env\"\n\nginkgo run --timeout=1h --poll-progress-after=60s --poll-progress-interval=30s --randomize-all --randomize-suites --keep-going -v --show-node-events \"$@\"\n"
  },
  {
    "path": "hack/test-integration.env",
    "content": "export KUBEBUILDER_CONTROLPLANE_START_TIMEOUT=2m\nexport GOMEGA_DEFAULT_EVENTUALLY_TIMEOUT=5s\nexport GOMEGA_DEFAULT_EVENTUALLY_POLLING_INTERVAL=200ms\nexport GOMEGA_DEFAULT_CONSISTENTLY_DURATION=5s\nexport GOMEGA_DEFAULT_CONSISTENTLY_POLLING_INTERVAL=200ms\n"
  },
  {
    "path": "hack/test-integration.sh",
    "content": "#!/usr/bin/env bash\n\nset -o nounset\nset -o pipefail\nset -o errexit\n\nENVTEST_K8S_VERSION=${ENVTEST_K8S_VERSION:-\"1.33\"}\n\n# shellcheck disable=SC1090\n# --use-env allows overwriting the envtest tools path via the KUBEBUILDER_ASSETS env var\nsource <(setup-envtest use --use-env -p env \"${ENVTEST_K8S_VERSION}\")\necho \"Using envtest binaries installed at '$KUBEBUILDER_ASSETS'\"\n\nsource \"$(dirname \"$0\")/test-integration.env\"\n\ntest_flags=\nif [ -n \"${CI:-}\" ] ; then\n  # Use Ginkgo timeout in CI to print everything that is buffered in GinkgoWriter.\n  test_flags+=\" --ginkgo.timeout=5m\"\nelse\n  # We don't want Ginkgo's timeout flag locally because it causes skipping the test cache.\n  timeout_flag=-timeout=5m\nfi\n\n# shellcheck disable=SC2086\ngo test ${timeout_flag:-} \"$@\" $test_flags\n"
  },
  {
    "path": "hack/test.sh",
    "content": "#!/usr/bin/env bash\n\nset -o nounset\nset -o pipefail\nset -o errexit\n\ntest_flags=\nif [ -n \"${CI:-}\" ] ; then\n  # Use Ginkgo timeout in CI to print everything that is buffered in GinkgoWriter.\n  test_flags+=\" --ginkgo.timeout=2m\"\nelse\n  # We don't want Ginkgo's timeout flag locally because it causes skipping the test cache.\n  timeout_flag=-timeout=2m\nfi\n\n# shellcheck disable=SC2086\ngo test -race ${timeout_flag:-} \"$@\" $test_flags\n"
  },
  {
    "path": "hack/tools.go",
    "content": "//go:build tools\n\n/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage hack\n\nimport (\n\t_ \"github.com/onsi/ginkgo/v2/ginkgo\"\n\t_ \"k8s.io/code-generator\"\n)\n"
  },
  {
    "path": "hack/tools.mk",
    "content": "TOOLS_BIN_DIR ?= hack/tools/bin\nexport PATH := $(abspath $(TOOLS_BIN_DIR)):$(PATH)\n\n# We use a file per tool and version as an indicator for make whether we need to install the tool or a different version\n# of the tool (make doesn't rerun the rule if the rule is changed).\n\n# Use this \"function\" to add the version file as a prerequisite for the tool target, e.g.:\n#   $(KUBECTL): $(call tool_version_file,$(KUBECTL),$(KUBECTL_VERSION))\ntool_version_file = $(TOOLS_BIN_DIR)/.version_$(subst $(TOOLS_BIN_DIR)/,,$(1))_$(2)\n\n# Use this \"function\" to get the version of a go module from go.mod, e.g.:\n#   GINKGO_VERSION ?= $(call version_gomod,github.com/onsi/ginkgo/v2)\nversion_gomod = $(shell go list -f '{{ .Version }}' -m $(1))\n\n# This target cleans up any previous version files for the given tool and creates the given version file.\n# This way, we can generically determine, which version was installed without calling each and every binary explicitly.\n$(TOOLS_BIN_DIR)/.version_%:\n\t@version_file=$@; rm -f $${version_file%_*}*\n\t@touch $@\n\nCONTROLLER_GEN := $(TOOLS_BIN_DIR)/controller-gen\n# renovate: datasource=github-releases depName=kubernetes-sigs/controller-tools\nCONTROLLER_GEN_VERSION ?= v0.19.0\n$(CONTROLLER_GEN): $(call tool_version_file,$(CONTROLLER_GEN),$(CONTROLLER_GEN_VERSION))\n\tGOBIN=$(abspath $(TOOLS_BIN_DIR)) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION)\n\nGINKGO := $(TOOLS_BIN_DIR)/ginkgo\nGINKGO_VERSION ?= $(call version_gomod,github.com/onsi/ginkgo/v2)\n$(GINKGO): $(call tool_version_file,$(GINKGO),$(GINKGO_VERSION))\n\tgo build -o $(GINKGO) github.com/onsi/ginkgo/v2/ginkgo\n\nGOLANGCI_LINT := $(TOOLS_BIN_DIR)/golangci-lint\n# renovate: datasource=github-releases depName=golangci/golangci-lint\nGOLANGCI_LINT_VERSION ?= v2.8.0\n$(GOLANGCI_LINT): $(call tool_version_file,$(GOLANGCI_LINT),$(GOLANGCI_LINT_VERSION))\n\tcurl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TOOLS_BIN_DIR) $(GOLANGCI_LINT_VERSION)\n\nKIND := $(TOOLS_BIN_DIR)/kind\n# renovate: datasource=github-releases depName=kubernetes-sigs/kind\nKIND_VERSION ?= v0.30.0\n$(KIND): $(call tool_version_file,$(KIND),$(KIND_VERSION))\n\tcurl -Lo $(KIND) https://kind.sigs.k8s.io/dl/$(KIND_VERSION)/kind-$(shell uname -s | tr '[:upper:]' '[:lower:]')-$(shell uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')\n\tchmod +x $(KIND)\n\nKO := $(TOOLS_BIN_DIR)/ko\n# renovate: datasource=github-releases depName=ko-build/ko\nKO_VERSION ?= v0.18.1\n$(KO): $(call tool_version_file,$(KO),$(KO_VERSION))\n\tGOBIN=$(abspath $(TOOLS_BIN_DIR)) go install github.com/google/ko@$(KO_VERSION)\n\nKUBECTL := $(TOOLS_BIN_DIR)/kubectl\n# renovate: datasource=github-releases depName=kubectl packageName=kubernetes/kubernetes\nKUBECTL_VERSION ?= v1.34.4\n$(KUBECTL): $(call tool_version_file,$(KUBECTL),$(KUBECTL_VERSION))\n\tcurl -Lo $(KUBECTL) https://dl.k8s.io/release/$(KUBECTL_VERSION)/bin/$(shell uname -s | tr '[:upper:]' '[:lower:]')/$(shell uname -m | sed 's/x86_64/amd64/')/kubectl\n\tchmod +x $(KUBECTL)\n\nSETUP_ENVTEST := $(TOOLS_BIN_DIR)/setup-envtest\nCONTROLLER_RUNTIME_VERSION ?= $(call version_gomod,sigs.k8s.io/controller-runtime)\n$(SETUP_ENVTEST): $(call tool_version_file,$(SETUP_ENVTEST),$(CONTROLLER_RUNTIME_VERSION))\n\tcurl -Lo $(SETUP_ENVTEST) https://github.com/kubernetes-sigs/controller-runtime/releases/download/$(CONTROLLER_RUNTIME_VERSION)/setup-envtest-$(shell uname -s | tr '[:upper:]' '[:lower:]')-$(shell uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')\n\tchmod +x $(SETUP_ENVTEST)\n\nSKAFFOLD := $(TOOLS_BIN_DIR)/skaffold\n# renovate: datasource=github-releases depName=GoogleContainerTools/skaffold\nSKAFFOLD_VERSION ?= v2.17.1\n$(SKAFFOLD): $(call tool_version_file,$(SKAFFOLD),$(SKAFFOLD_VERSION))\n\tcurl -Lo $(SKAFFOLD) https://storage.googleapis.com/skaffold/releases/$(SKAFFOLD_VERSION)/skaffold-$(shell uname -s | tr '[:upper:]' '[:lower:]')-$(shell uname -m | sed 's/x86_64/amd64/')\n\tchmod +x $(SKAFFOLD)\n\nVGOPATH := $(TOOLS_BIN_DIR)/vgopath\n# renovate: datasource=github-releases depName=ironcore-dev/vgopath\nVGOPATH_VERSION ?= v0.1.10\n$(VGOPATH): $(call tool_version_file,$(VGOPATH),$(VGOPATH_VERSION))\n\tGOBIN=$(abspath $(TOOLS_BIN_DIR)) go install github.com/ironcore-dev/vgopath@$(VGOPATH_VERSION)\n\nYQ := $(TOOLS_BIN_DIR)/yq\n# renovate: datasource=github-releases depName=mikefarah/yq\nYQ_VERSION ?= v4.52.2\n$(YQ): $(call tool_version_file,$(YQ),$(YQ_VERSION))\n\tcurl -Lo $(YQ) https://github.com/mikefarah/yq/releases/download/$(YQ_VERSION)/yq_$(shell uname -s | tr '[:upper:]' '[:lower:]')_$(shell uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')\n\tchmod +x $(YQ)\n"
  },
  {
    "path": "hack/update-codegen.sh",
    "content": "#!/usr/bin/env bash\n# Copyright 2023 Tim Ebert.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -o errexit\nset -o nounset\nset -o pipefail\n\nSCRIPT_DIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" &> /dev/null && pwd )\"\n\n# fetch code-generator module to execute the scripts from the modcache (we don't vendor here)\nCODE_GENERATOR_DIR=\"$(go list -m -tags tools -f '{{ .Dir }}' k8s.io/code-generator)\"\nsource \"${CODE_GENERATOR_DIR}\"/kube_codegen.sh\n\n# setup virtual GOPATH\n# k8s.io/code-generator does not work outside GOPATH, see https://github.com/kubernetes/kubernetes/issues/86753.\nsource \"$SCRIPT_DIR\"/vgopath-setup.sh\n\n# We need to explicitly pass GO111MODULE=off to k8s.io/code-generator as it is significantly slower otherwise,\n# see https://github.com/kubernetes/code-generator/issues/100.\nexport GO111MODULE=off\n\n# sharder config API\n\nsharder_config_group() {\n  echo \"Generating sharder config API group\"\n\n  kube::codegen::gen_helpers \\\n      --boilerplate \"${SCRIPT_DIR}/boilerplate.go.txt\" \\\n      \"${SCRIPT_DIR}/../pkg/apis\"\n}\n\nwebhosting_config_group() {\n  echo \"Generating webhosting-operator config API group\"\n\n  kube::codegen::gen_helpers \\\n      --boilerplate \"${SCRIPT_DIR}/boilerplate.go.txt\" \\\n      \"${SCRIPT_DIR}/../webhosting-operator/pkg/apis\"\n}\n\nsharder_config_group\nwebhosting_config_group\n"
  },
  {
    "path": "hack/vgopath-setup.sh",
    "content": "# Ensure that if GOPATH is set, the GOPATH/{bin,pkg} directory exists. This might not be the case in CI.\n# As we will create a symlink against the bin folder we need to make sure that the bin directory is\n# present in the GOPATH.\nif [ -n \"${GOPATH:-}\" ] && [ ! -d \"$GOPATH/bin\" ]; then mkdir -p \"$GOPATH/bin\"; fi\nif [ -n \"${GOPATH:-}\" ] && [ ! -d \"$GOPATH/pkg\" ]; then mkdir -p \"$GOPATH/pkg\"; fi\n\nVIRTUAL_GOPATH=\"$(mktemp -d)\"\ntrap 'rm -rf \"$VIRTUAL_GOPATH\"' EXIT\n\n# Setup virtual GOPATH\ngo mod download && vgopath -o \"$VIRTUAL_GOPATH\"\n\nexport GOPATH=\"$VIRTUAL_GOPATH\"\n"
  },
  {
    "path": "pkg/apis/config/doc.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// +groupName=config.sharding.timebertt.dev\n\npackage config // import \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config\"\n"
  },
  {
    "path": "pkg/apis/config/v1alpha1/defaults.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1\n\nimport (\n\t\"time\"\n\n\tadmissionregistrationv1 \"k8s.io/api/admissionregistration/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/client-go/tools/leaderelection/resourcelock\"\n\tcomponentbaseconfigv1alpha1 \"k8s.io/component-base/config/v1alpha1\"\n\t\"k8s.io/utils/ptr\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n)\n\nfunc addDefaultingFuncs(scheme *runtime.Scheme) error {\n\treturn RegisterDefaults(scheme)\n}\n\nfunc SetDefaults_SharderConfig(obj *SharderConfig) {\n\tif obj.ClientConnection == nil {\n\t\tobj.ClientConnection = &componentbaseconfigv1alpha1.ClientConnectionConfiguration{}\n\t}\n\tif obj.LeaderElection == nil {\n\t\tobj.LeaderElection = &componentbaseconfigv1alpha1.LeaderElectionConfiguration{}\n\t}\n\tif obj.Debugging == nil {\n\t\tobj.Debugging = &componentbaseconfigv1alpha1.DebuggingConfiguration{}\n\t}\n\n\tif obj.GracefulShutdownTimeout == nil {\n\t\tobj.GracefulShutdownTimeout = &metav1.Duration{Duration: 15 * time.Second}\n\t}\n}\n\nfunc SetDefaults_LeaderElectionConfiguration(obj *componentbaseconfigv1alpha1.LeaderElectionConfiguration) {\n\tif obj.ResourceLock == \"\" {\n\t\tobj.ResourceLock = resourcelock.LeasesResourceLock\n\t}\n\n\tcomponentbaseconfigv1alpha1.RecommendedDefaultLeaderElectionConfiguration(obj)\n\n\tif obj.ResourceName == \"\" {\n\t\tobj.ResourceName = \"sharder\"\n\t}\n\tif obj.ResourceNamespace == \"\" {\n\t\tobj.ResourceNamespace = shardingv1alpha1.NamespaceSystem\n\t}\n}\n\nfunc SetDefaults_DebuggingConfiguration(obj *componentbaseconfigv1alpha1.DebuggingConfiguration) {\n\tcomponentbaseconfigv1alpha1.RecommendedDebuggingConfiguration(obj)\n\n\tif obj.EnableContentionProfiling == nil {\n\t\tobj.EnableContentionProfiling = ptr.To(false)\n\t}\n}\n\nfunc SetDefaults_HealthEndpoint(obj *HealthEndpoint) {\n\tif obj.BindAddress == \"\" {\n\t\tobj.BindAddress = \":8081\"\n\t}\n}\n\nfunc SetDefaults_MetricsEndpoint(obj *MetricsEndpoint) {\n\tif obj.BindAddress == \"\" {\n\t\tobj.BindAddress = \":8080\"\n\t}\n}\n\nfunc SetDefaults_Controller(obj *Controller) {\n\tif obj.Sharder == nil {\n\t\tobj.Sharder = &SharderController{}\n\t}\n}\n\nfunc SetDefaults_SharderController(obj *SharderController) {\n\tif obj.SyncPeriod == nil {\n\t\tobj.SyncPeriod = &metav1.Duration{Duration: 5 * time.Minute}\n\t}\n\tif obj.ConcurrentMoves == nil {\n\t\tobj.ConcurrentMoves = ptr.To[int32](100)\n\t}\n}\n\nfunc SetDefaults_Webhook(obj *Webhook) {\n\tif obj.Server == nil {\n\t\tobj.Server = &WebhookServer{}\n\t}\n\n\tif obj.Config == nil {\n\t\tobj.Config = &WebhookConfig{}\n\t}\n}\n\nfunc SetDefaults_WebhookConfig(obj *WebhookConfig) {\n\tif obj.ClientConfig == nil {\n\t\tobj.ClientConfig = &admissionregistrationv1.WebhookClientConfig{}\n\t}\n\n\tif obj.NamespaceSelector == nil {\n\t\tobj.NamespaceSelector = &metav1.LabelSelector{\n\t\t\tMatchExpressions: []metav1.LabelSelectorRequirement{{\n\t\t\t\tKey:      corev1.LabelMetadataName,\n\t\t\t\tOperator: metav1.LabelSelectorOpNotIn,\n\t\t\t\tValues:   []string{metav1.NamespaceSystem, shardingv1alpha1.NamespaceSystem},\n\t\t\t}},\n\t\t}\n\t}\n}\n\nfunc SetDefaults_WebhookClientConfig(obj *admissionregistrationv1.WebhookClientConfig) {\n\tif obj.URL == nil && obj.Service == nil {\n\t\tobj.Service = &admissionregistrationv1.ServiceReference{}\n\t}\n}\n\nfunc SetDefaults_ServiceReference(obj *admissionregistrationv1.ServiceReference) {\n\tif obj.Namespace == \"\" {\n\t\tobj.Namespace = shardingv1alpha1.NamespaceSystem\n\t}\n\tif obj.Name == \"\" {\n\t\tobj.Name = \"sharder\"\n\t}\n}\n"
  },
  {
    "path": "pkg/apis/config/v1alpha1/defaults_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1_test\n\nimport (\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tadmissionregistrationv1 \"k8s.io/api/admissionregistration/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\tcomponentbaseconfigv1alpha1 \"k8s.io/component-base/config/v1alpha1\"\n\t\"k8s.io/utils/ptr\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n)\n\nvar _ = Describe(\"SharderConfig defaulting\", func() {\n\tvar obj *SharderConfig\n\n\tBeforeEach(func() {\n\t\tobj = &SharderConfig{}\n\t})\n\n\tContext(\"ClientConnectionConfiguration\", func() {\n\t\tIt(\"should not set any default values\", func() {\n\t\t\tSetObjectDefaults_SharderConfig(obj)\n\n\t\t\tExpect(obj.ClientConnection).To(Equal(&componentbaseconfigv1alpha1.ClientConnectionConfiguration{}))\n\t\t})\n\t})\n\n\tContext(\"LeaderElectionConfiguration\", func() {\n\t\tIt(\"should set default values\", func() {\n\t\t\tSetObjectDefaults_SharderConfig(obj)\n\n\t\t\tExpect(obj.LeaderElection).To(Equal(&componentbaseconfigv1alpha1.LeaderElectionConfiguration{\n\t\t\t\tLeaderElect:       ptr.To(true),\n\t\t\t\tLeaseDuration:     metav1.Duration{Duration: 15 * time.Second},\n\t\t\t\tRenewDeadline:     metav1.Duration{Duration: 10 * time.Second},\n\t\t\t\tRetryPeriod:       metav1.Duration{Duration: 2 * time.Second},\n\t\t\t\tResourceLock:      \"leases\",\n\t\t\t\tResourceName:      \"sharder\",\n\t\t\t\tResourceNamespace: \"sharding-system\",\n\t\t\t}))\n\t\t})\n\t})\n\n\tContext(\"DebuggingConfiguration\", func() {\n\t\tIt(\"should set default values\", func() {\n\t\t\tSetObjectDefaults_SharderConfig(obj)\n\n\t\t\tExpect(obj.Debugging).To(Equal(&componentbaseconfigv1alpha1.DebuggingConfiguration{\n\t\t\t\tEnableProfiling:           ptr.To(true),\n\t\t\t\tEnableContentionProfiling: ptr.To(false),\n\t\t\t}))\n\t\t})\n\t})\n\n\tContext(\"manager settings\", func() {\n\t\tIt(\"should set default values\", func() {\n\t\t\tSetObjectDefaults_SharderConfig(obj)\n\n\t\t\tExpect(obj.Health).To(Equal(HealthEndpoint{\n\t\t\t\tBindAddress: \":8081\",\n\t\t\t}))\n\t\t\tExpect(obj.Metrics).To(Equal(MetricsEndpoint{\n\t\t\t\tBindAddress: \":8080\",\n\t\t\t}))\n\t\t\tExpect(obj.GracefulShutdownTimeout).To(Equal(&metav1.Duration{Duration: 15 * time.Second}))\n\t\t})\n\t})\n\n\tContext(\"controller config\", func() {\n\t\tIt(\"should set default values\", func() {\n\t\t\tSetObjectDefaults_SharderConfig(obj)\n\n\t\t\tExpect(obj.Controller).To(Equal(Controller{\n\t\t\t\tSharder: &SharderController{\n\t\t\t\t\tSyncPeriod:      &metav1.Duration{Duration: 5 * time.Minute},\n\t\t\t\t\tConcurrentMoves: ptr.To[int32](100),\n\t\t\t\t},\n\t\t\t}))\n\t\t})\n\t})\n\n\tContext(\"webhook config\", func() {\n\t\tIt(\"should set default values\", func() {\n\t\t\tSetObjectDefaults_SharderConfig(obj)\n\n\t\t\tExpect(obj.Webhook).To(Equal(Webhook{\n\t\t\t\tServer: &WebhookServer{},\n\t\t\t\tConfig: &WebhookConfig{\n\t\t\t\t\tClientConfig: &admissionregistrationv1.WebhookClientConfig{\n\t\t\t\t\t\tService: &admissionregistrationv1.ServiceReference{\n\t\t\t\t\t\t\tNamespace: \"sharding-system\",\n\t\t\t\t\t\t\tName:      \"sharder\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tNamespaceSelector: &metav1.LabelSelector{\n\t\t\t\t\t\tMatchExpressions: []metav1.LabelSelectorRequirement{{\n\t\t\t\t\t\t\tKey:      \"kubernetes.io/metadata.name\",\n\t\t\t\t\t\t\tOperator: \"NotIn\",\n\t\t\t\t\t\t\tValues:   []string{\"kube-system\", \"sharding-system\"},\n\t\t\t\t\t\t}},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}))\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/apis/config/v1alpha1/doc.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// +k8s:defaulter-gen=TypeMeta\n\npackage v1alpha1 // import \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n"
  },
  {
    "path": "pkg/apis/config/v1alpha1/register.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package v1alpha1 contains API Schema definitions for the config v1alpha1 API group\n// +kubebuilder:object:generate=true\n// +groupName=config.sharding.timebertt.dev\npackage v1alpha1\n\nimport (\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n)\n\n// GroupName is the group name used in this package.\nconst GroupName = \"config.sharding.timebertt.dev\"\n\n// SchemeGroupVersion is group version used to register these objects\nvar SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: \"v1alpha1\"}\n\nvar (\n\t// SchemeBuilder is a new Scheme Builder which registers our API.\n\tSchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes, addDefaultingFuncs)\n\t// AddToScheme is a reference to the Scheme Builder's AddToScheme function.\n\tAddToScheme = SchemeBuilder.AddToScheme\n)\n\n// Adds the list of known types to the given scheme.\nfunc addKnownTypes(scheme *runtime.Scheme) error {\n\tscheme.AddKnownTypes(SchemeGroupVersion,\n\t\t&SharderConfig{},\n\t)\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/apis/config/v1alpha1/types.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1\n\nimport (\n\tadmissionregistrationv1 \"k8s.io/api/admissionregistration/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\tcomponentbaseconfigv1alpha1 \"k8s.io/component-base/config/v1alpha1\"\n)\n\n//+kubebuilder:object:root=true\n\n// SharderConfig is the configuration object for the sharder component.\ntype SharderConfig struct {\n\tmetav1.TypeMeta `json:\",inline\"`\n\n\t// ClientConnection holds configuration for the kubernetes API clients.\n\t// +optional\n\tClientConnection *componentbaseconfigv1alpha1.ClientConnectionConfiguration `json:\"clientConnection,omitempty\"`\n\t// LeaderElection is the LeaderElection config to be used when configuring\n\t// the manager.Manager leader election\n\t// +optional\n\tLeaderElection *componentbaseconfigv1alpha1.LeaderElectionConfiguration `json:\"leaderElection,omitempty\"`\n\t// Debugging holds configuration for Debugging related features.\n\t// +optional\n\tDebugging *componentbaseconfigv1alpha1.DebuggingConfiguration `json:\"debugging,omitempty\"`\n\t// Health contains the controller health configuration\n\tHealth HealthEndpoint `json:\"health\"`\n\t// Metrics contains the controller metrics configuration\n\tMetrics MetricsEndpoint `json:\"metrics\"`\n\t// Controller configures the sharder's controllers.\n\tController Controller `json:\"controller\"`\n\t// Webhook configures webhooks and the webhook server.\n\tWebhook Webhook `json:\"webhook\"`\n\t// GracefulShutdownTimeout is the duration given to runnable to stop before the manager actually returns on stop.\n\t// To disable graceful shutdown, set it to 0s.\n\t// To use graceful shutdown without timeout, set to a negative duration, e.G. -1s.\n\t// The graceful shutdown is skipped for safety reasons in case the leader election lease is lost.\n\t// Defaults to 15s\n\tGracefulShutdownTimeout *metav1.Duration `json:\"gracefulShutDown,omitempty\"`\n}\n\n// HealthEndpoint defines the health configs.\ntype HealthEndpoint struct {\n\t// BindAddress is the TCP address that the controller should bind to\n\t// for serving health probes\n\t// It can be set to \"0\" to disable serving the health probe.\n\t// Defaults to :8081\n\t// +optional\n\tBindAddress string `json:\"bindAddress,omitempty\"`\n}\n\n// MetricsEndpoint defines the metrics configs.\ntype MetricsEndpoint struct {\n\t// BindAddress is the TCP address that the controller should bind to\n\t// for serving prometheus metrics.\n\t// It can be set to \"0\" to disable the metrics serving.\n\t// Defaults to :8080\n\t// +optional\n\tBindAddress string `json:\"bindAddress,omitempty\"`\n}\n\n// Controller configures the sharder's controllers.\ntype Controller struct {\n\t// Sharder configures the sharder controller.\n\t// +optional\n\tSharder *SharderController `json:\"sharder,omitempty\"`\n}\n\n// SharderController configures the sharder controller.\ntype SharderController struct {\n\t// SyncPeriod configures how often a periodic resync of all object assignments in a ring is performed.\n\t// Defaults to 5m\n\t// +optional\n\tSyncPeriod *metav1.Duration `json:\"syncPeriod,omitempty\"`\n\t// ConcurrentMoves configures how many objects of the same ControllerRing are moved (or drained) concurrently at\n\t// maximum.\n\t// Defaults to 100\n\t// +optional\n\tConcurrentMoves *int32 `json:\"concurrentMoves,omitempty\"`\n}\n\n// Webhook configures webhooks and the webhook server.\ntype Webhook struct {\n\t// Server configures the sharder's webhook server.\n\t// +optional\n\tServer *WebhookServer `json:\"server,omitempty\"`\n\t// Config configures the sharder's MutatingWebhookConfiguration objects.\n\t// +optional\n\tConfig *WebhookConfig `json:\"config,omitempty\"`\n}\n\n// WebhookServer configures the webhook server.\ntype WebhookServer struct {\n\t// CertDir is the directory that contains the server key and certificate.\n\t// Defaults to /tmp/k8s-webhook-server/serving-certs\n\t// +optional\n\tCertDir *string `json:\"certDir,omitempty\"`\n\t// CertName is the server certificate name.\n\t// Defaults to tls.crt\n\t// +optional\n\tCertName *string `json:\"certName,omitempty\"`\n\t// KeyName is the server key name.\n\t// Defaults to tls.key\n\t// +optional\n\tKeyName *string `json:\"keyName,omitempty\"`\n}\n\n// WebhookConfig configures the sharder's MutatingWebhookConfiguration objects.\ntype WebhookConfig struct {\n\t// Annotations are additional annotations that should be added to all webhook configs.\n\t// +optional\n\tAnnotations map[string]string `json:\"annotations,omitempty\"`\n\t// ClientConfig configures the webhook configs' target.\n\t// Defaults to a service reference to sharding-system/sharder.\n\t// +optional\n\tClientConfig *admissionregistrationv1.WebhookClientConfig `json:\"clientConfig,omitempty\"`\n\t// NamespaceSelector overwrites the webhook configs' default namespaceSelector.\n\t// Note: changing/unsetting this selector will not remove labels from objects in namespaces that were previously\n\t// included.\n\t// Defaults to excluding the kube-system and sharding-system namespaces\n\t// +optional\n\tNamespaceSelector *metav1.LabelSelector `json:\"namespaceSelector,omitempty\"`\n}\n"
  },
  {
    "path": "pkg/apis/config/v1alpha1/v1alpha1_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestV1alpha1(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Sharder Config API V1alpha1 Suite\")\n}\n"
  },
  {
    "path": "pkg/apis/config/v1alpha1/zz_generated.deepcopy.go",
    "content": "//go:build !ignore_autogenerated\n\n/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Code generated by controller-gen. DO NOT EDIT.\n\npackage v1alpha1\n\nimport (\n\tadmissionregistrationv1 \"k8s.io/api/admissionregistration/v1\"\n\t\"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\tconfigv1alpha1 \"k8s.io/component-base/config/v1alpha1\"\n)\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *Controller) DeepCopyInto(out *Controller) {\n\t*out = *in\n\tif in.Sharder != nil {\n\t\tin, out := &in.Sharder, &out.Sharder\n\t\t*out = new(SharderController)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Controller.\nfunc (in *Controller) DeepCopy() *Controller {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(Controller)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *HealthEndpoint) DeepCopyInto(out *HealthEndpoint) {\n\t*out = *in\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthEndpoint.\nfunc (in *HealthEndpoint) DeepCopy() *HealthEndpoint {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(HealthEndpoint)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *MetricsEndpoint) DeepCopyInto(out *MetricsEndpoint) {\n\t*out = *in\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsEndpoint.\nfunc (in *MetricsEndpoint) DeepCopy() *MetricsEndpoint {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(MetricsEndpoint)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *SharderConfig) DeepCopyInto(out *SharderConfig) {\n\t*out = *in\n\tout.TypeMeta = in.TypeMeta\n\tif in.ClientConnection != nil {\n\t\tin, out := &in.ClientConnection, &out.ClientConnection\n\t\t*out = new(configv1alpha1.ClientConnectionConfiguration)\n\t\t**out = **in\n\t}\n\tif in.LeaderElection != nil {\n\t\tin, out := &in.LeaderElection, &out.LeaderElection\n\t\t*out = new(configv1alpha1.LeaderElectionConfiguration)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n\tif in.Debugging != nil {\n\t\tin, out := &in.Debugging, &out.Debugging\n\t\t*out = new(configv1alpha1.DebuggingConfiguration)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n\tout.Health = in.Health\n\tout.Metrics = in.Metrics\n\tin.Controller.DeepCopyInto(&out.Controller)\n\tin.Webhook.DeepCopyInto(&out.Webhook)\n\tif in.GracefulShutdownTimeout != nil {\n\t\tin, out := &in.GracefulShutdownTimeout, &out.GracefulShutdownTimeout\n\t\t*out = new(v1.Duration)\n\t\t**out = **in\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SharderConfig.\nfunc (in *SharderConfig) DeepCopy() *SharderConfig {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(SharderConfig)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.\nfunc (in *SharderConfig) DeepCopyObject() runtime.Object {\n\tif c := in.DeepCopy(); c != nil {\n\t\treturn c\n\t}\n\treturn nil\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *SharderController) DeepCopyInto(out *SharderController) {\n\t*out = *in\n\tif in.SyncPeriod != nil {\n\t\tin, out := &in.SyncPeriod, &out.SyncPeriod\n\t\t*out = new(v1.Duration)\n\t\t**out = **in\n\t}\n\tif in.ConcurrentMoves != nil {\n\t\tin, out := &in.ConcurrentMoves, &out.ConcurrentMoves\n\t\t*out = new(int32)\n\t\t**out = **in\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SharderController.\nfunc (in *SharderController) DeepCopy() *SharderController {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(SharderController)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *Webhook) DeepCopyInto(out *Webhook) {\n\t*out = *in\n\tif in.Server != nil {\n\t\tin, out := &in.Server, &out.Server\n\t\t*out = new(WebhookServer)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n\tif in.Config != nil {\n\t\tin, out := &in.Config, &out.Config\n\t\t*out = new(WebhookConfig)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Webhook.\nfunc (in *Webhook) DeepCopy() *Webhook {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(Webhook)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *WebhookConfig) DeepCopyInto(out *WebhookConfig) {\n\t*out = *in\n\tif in.Annotations != nil {\n\t\tin, out := &in.Annotations, &out.Annotations\n\t\t*out = make(map[string]string, len(*in))\n\t\tfor key, val := range *in {\n\t\t\t(*out)[key] = val\n\t\t}\n\t}\n\tif in.ClientConfig != nil {\n\t\tin, out := &in.ClientConfig, &out.ClientConfig\n\t\t*out = new(admissionregistrationv1.WebhookClientConfig)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n\tif in.NamespaceSelector != nil {\n\t\tin, out := &in.NamespaceSelector, &out.NamespaceSelector\n\t\t*out = new(v1.LabelSelector)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfig.\nfunc (in *WebhookConfig) DeepCopy() *WebhookConfig {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(WebhookConfig)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *WebhookServer) DeepCopyInto(out *WebhookServer) {\n\t*out = *in\n\tif in.CertDir != nil {\n\t\tin, out := &in.CertDir, &out.CertDir\n\t\t*out = new(string)\n\t\t**out = **in\n\t}\n\tif in.CertName != nil {\n\t\tin, out := &in.CertName, &out.CertName\n\t\t*out = new(string)\n\t\t**out = **in\n\t}\n\tif in.KeyName != nil {\n\t\tin, out := &in.KeyName, &out.KeyName\n\t\t*out = new(string)\n\t\t**out = **in\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookServer.\nfunc (in *WebhookServer) DeepCopy() *WebhookServer {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(WebhookServer)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n"
  },
  {
    "path": "pkg/apis/config/v1alpha1/zz_generated.defaults.go",
    "content": "//go:build !ignore_autogenerated\n// +build !ignore_autogenerated\n\n/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Code generated by defaulter-gen. DO NOT EDIT.\n\npackage v1alpha1\n\nimport (\n\truntime \"k8s.io/apimachinery/pkg/runtime\"\n)\n\n// RegisterDefaults adds defaulters functions to the given scheme.\n// Public to allow building arbitrary schemes.\n// All generated defaulters are covering - they call all nested defaulters.\nfunc RegisterDefaults(scheme *runtime.Scheme) error {\n\tscheme.AddTypeDefaultingFunc(&SharderConfig{}, func(obj interface{}) { SetObjectDefaults_SharderConfig(obj.(*SharderConfig)) })\n\treturn nil\n}\n\nfunc SetObjectDefaults_SharderConfig(in *SharderConfig) {\n\tSetDefaults_SharderConfig(in)\n\tif in.LeaderElection != nil {\n\t\tSetDefaults_LeaderElectionConfiguration(in.LeaderElection)\n\t}\n\tif in.Debugging != nil {\n\t\tSetDefaults_DebuggingConfiguration(in.Debugging)\n\t}\n\tSetDefaults_HealthEndpoint(&in.Health)\n\tSetDefaults_MetricsEndpoint(&in.Metrics)\n\tSetDefaults_Controller(&in.Controller)\n\tif in.Controller.Sharder != nil {\n\t\tSetDefaults_SharderController(in.Controller.Sharder)\n\t}\n\tSetDefaults_Webhook(&in.Webhook)\n\tif in.Webhook.Config != nil {\n\t\tSetDefaults_WebhookConfig(in.Webhook.Config)\n\t\tif in.Webhook.Config.ClientConfig != nil {\n\t\t\tSetDefaults_WebhookClientConfig(in.Webhook.Config.ClientConfig)\n\t\t\tif in.Webhook.Config.ClientConfig.Service != nil {\n\t\t\t\tSetDefaults_ServiceReference(in.Webhook.Config.ClientConfig.Service)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "pkg/apis/sharding/doc.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// +groupName=sharding.timebertt.dev\n\npackage sharding // import \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding\"\n"
  },
  {
    "path": "pkg/apis/sharding/v1alpha1/constants.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1\n\n// This file contains API-related constants for the sharding implementation, e.g. well-known annotations and labels.\n\nconst (\n\t// NamespaceSystem is the namespace where the sharding system components run.\n\tNamespaceSystem = \"sharding-system\"\n\t// AppControllerSharding is the value for the \"app.kubernetes.io/name\" label used for objects related to controller\n\t// sharding.\n\tAppControllerSharding = \"controller-sharding\"\n\n\t// alphaPrefix is a common prefix for all well-known annotations and labels in this API version package.\n\talphaPrefix = \"alpha.sharding.timebertt.dev/\"\n\n\t// LabelControllerRing is the label on objects that identifies the ControllerRing that the object belongs to.\n\tLabelControllerRing = alphaPrefix + \"controllerring\"\n\t// LabelState is the label on Lease objects that reflects the state of a shard for observability purposes.\n\t// This label is maintained by the shardlease controller.\n\tLabelState = alphaPrefix + \"state\"\n\t// LabelShardPrefix is the qualified prefix for a label on sharded objects that holds the name of the responsible\n\t// shard within a ring. Use LabelShard to compute the full label key for a ring.\n\tLabelShardPrefix = \"shard.\" + alphaPrefix\n\t// LabelDrainPrefix is the qualified prefix for a label on sharded objects that instructs the responsible shard within\n\t// a ring to stop reconciling the object and remove both the shard and drain label. Use LabelDrain to compute the full\n\t// label key for a ring.\n\tLabelDrainPrefix = \"drain.\" + alphaPrefix\n\n\t// IdentityShardLeaseController is the identity that the shardlease controller uses to acquire leases of unavailable\n\t// shards.\n\tIdentityShardLeaseController = \"shardlease-controller\"\n)\n\n// LabelShard returns the label on sharded objects that holds the name of the responsible shard within a ring.\nfunc LabelShard(ringName string) string {\n\treturn LabelShardPrefix + ringName\n}\n\n// LabelDrain returns the label on sharded objects that instructs the responsible shard within a ring to stop reconciling\n// the object and remove both the shard and drain label.\nfunc LabelDrain(ringName string) string {\n\treturn LabelDrainPrefix + ringName\n}\n"
  },
  {
    "path": "pkg/apis/sharding/v1alpha1/constants_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1_test\n\nimport (\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n)\n\nvar _ = Describe(\"#LabelShard\", func() {\n\tIt(\"should append the ControllerRing name\", func() {\n\t\tExpect(LabelShard(\"foo\")).To(Equal(\"shard.alpha.sharding.timebertt.dev/foo\"))\n\t})\n})\n\nvar _ = Describe(\"#LabelDrain\", func() {\n\tIt(\"should append the ControllerRing name\", func() {\n\t\tExpect(LabelDrain(\"foo\")).To(Equal(\"drain.alpha.sharding.timebertt.dev/foo\"))\n\t})\n})\n"
  },
  {
    "path": "pkg/apis/sharding/v1alpha1/doc.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1 // import \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n"
  },
  {
    "path": "pkg/apis/sharding/v1alpha1/register.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package v1alpha1 contains API Schema definitions for the sharding v1alpha1 API group\n// +kubebuilder:object:generate=true\n// +groupName=sharding.timebertt.dev\npackage v1alpha1\n\nimport (\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n)\n\n// GroupName is the group name used in this package.\nconst GroupName = \"sharding.timebertt.dev\"\n\n// SchemeGroupVersion is group version used to register these objects\nvar SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: \"v1alpha1\"}\n\nvar (\n\t// SchemeBuilder is a new Scheme Builder which registers our API.\n\tSchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)\n\t// AddToScheme is a reference to the Scheme Builder's AddToScheme function.\n\tAddToScheme = SchemeBuilder.AddToScheme\n)\n\n// Adds the list of known types to the given scheme.\nfunc addKnownTypes(scheme *runtime.Scheme) error {\n\tscheme.AddKnownTypes(SchemeGroupVersion,\n\t\t&ControllerRing{},\n\t\t&ControllerRingList{},\n\t)\n\n\tmetav1.AddToGroupVersion(scheme, SchemeGroupVersion)\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/apis/sharding/v1alpha1/types_controllerring.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1\n\nimport (\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n)\n\n//+kubebuilder:object:root=true\n//+kubebuilder:resource:scope=Cluster\n//+kubebuilder:subresource:status\n//+kubebuilder:printcolumn:name=\"Ready\",type=\"string\",JSONPath=`.status.conditions[?(@.type == \"Ready\")].status`\n//+kubebuilder:printcolumn:name=\"Available\",type=string,JSONPath=`.status.availableShards`\n//+kubebuilder:printcolumn:name=\"Shards\",type=string,JSONPath=`.status.shards`\n//+kubebuilder:printcolumn:name=\"Age\",type=\"date\",JSONPath=`.metadata.creationTimestamp`\n//+kubebuilder:validation:XValidation:rule=\"size(self.metadata.name) <= 63\",message=\"ControllerRing name must not be longer than 63 characters\"\n\n// ControllerRing declares a virtual ring of sharded controller instances. Objects of the specified resources are\n// distributed across shards of this ring. Objects in all namespaces are considered unless a namespaceSelector is\n// specified.\ntype ControllerRing struct {\n\tmetav1.TypeMeta `json:\",inline\"`\n\t// Standard object's metadata.\n\t// +optional\n\tmetav1.ObjectMeta `json:\"metadata,omitempty\"`\n\t// Spec contains the specification of the desired behavior of the ControllerRing.\n\t// +optional\n\tSpec ControllerRingSpec `json:\"spec,omitempty\"`\n\t// Status contains the most recently observed status of the ControllerRing.\n\t// +optional\n\tStatus ControllerRingStatus `json:\"status,omitempty\"`\n}\n\n//+kubebuilder:object:root=true\n\n// ControllerRingList contains a list of ControllerRings.\ntype ControllerRingList struct {\n\tmetav1.TypeMeta `json:\",inline\"`\n\t// Standard list metadata.\n\t// +optional\n\tmetav1.ListMeta `json:\"metadata,omitempty\"`\n\t// Items is the list of ControllerRings.\n\tItems []ControllerRing `json:\"items\"`\n}\n\n// ControllerRingSpec defines the desired state of a ControllerRing.\ntype ControllerRingSpec struct {\n\t// Resources specifies the list of resources that are distributed across shards in this ControllerRing.\n\t// +optional\n\t// +listType=map\n\t// +listMapKey=group\n\t// +listMapKey=resource\n\tResources []RingResource `json:\"resources,omitempty\"`\n\t// NamespaceSelector overwrites the webhook configs' namespaceSelector.\n\t// If set, this selector should exclude the kube-system and sharding-system namespaces.\n\t// If omitted, the default namespaceSelector from the SharderConfig is used.\n\t// Note: changing/unsetting this selector will not remove labels from objects in namespaces that were previously\n\t// included.\n\t// +optional\n\tNamespaceSelector *metav1.LabelSelector `json:\"namespaceSelector,omitempty\"`\n}\n\n// RingResource specifies a resource along with controlled resources that is distributed across shards in a ring.\ntype RingResource struct {\n\t// GroupResource specifies the resource that is distributed across shards in a ring.\n\t// This resource is the controller's main resource, i.e., the resource of which it updates the object status.\n\tmetav1.GroupResource `json:\",inline\"`\n\n\t// ControlledResources are additional resources that are distributed across shards in the ControllerRing.\n\t// These resources are controlled by the controller's main resource, i.e., they have an owner reference with\n\t// controller=true back to the GroupResource of this RingResource.\n\t// Typically, the controller also watches objects of this resource and enqueues the owning object (of the main\n\t// resource) whenever the status of a controlled object changes.\n\t// +optional\n\t// +listType=map\n\t// +listMapKey=group\n\t// +listMapKey=resource\n\tControlledResources []metav1.GroupResource `json:\"controlledResources,omitempty\"`\n}\n\nconst (\n\t// ControllerRingReady is the condition type for the \"Ready\" condition on ControllerRings.\n\tControllerRingReady = \"Ready\"\n)\n\n// ControllerRingStatus defines the observed state of a ControllerRing.\ntype ControllerRingStatus struct {\n\t// The generation observed by the ControllerRing controller.\n\t// +optional\n\tObservedGeneration int64 `json:\"observedGeneration,omitempty\"`\n\t// Shards is the total number of shards of this ring.\n\tShards int32 `json:\"shards\"`\n\t// AvailableShards is the total number of available shards of this ring.\n\tAvailableShards int32 `json:\"availableShards\"`\n\t// Conditions represents the observations of a foo's current state.\n\t// Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\"\n\t// +listType=map\n\t// +listMapKey=type\n\t// +optional\n\tConditions []metav1.Condition `json:\"conditions,omitempty\"`\n}\n\n// LeaseSelector returns a label selector for selecting shard Lease objects belonging to this ControllerRing.\nfunc (c *ControllerRing) LeaseSelector() labels.Selector {\n\treturn labels.SelectorFromSet(labels.Set{LabelControllerRing: c.Name})\n}\n\n// LabelShard returns the label on sharded objects that holds the name of the responsible shard within this ControllerRing.\nfunc (c *ControllerRing) LabelShard() string {\n\treturn LabelShard(c.Name)\n}\n\n// LabelDrain returns the label on sharded objects that instructs the responsible shard within this ControllerRing to stop\n// reconciling the object and remove both the shard and drain label.\nfunc (c *ControllerRing) LabelDrain() string {\n\treturn LabelDrain(c.Name)\n}\n"
  },
  {
    "path": "pkg/apis/sharding/v1alpha1/types_controllerring_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1_test\n\nimport (\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n)\n\nvar _ = Describe(\"ControllerRing\", func() {\n\tvar ring *ControllerRing\n\n\tBeforeEach(func() {\n\t\tring = &ControllerRing{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tName: \"operator\",\n\t\t\t},\n\t\t\tSpec: ControllerRingSpec{\n\t\t\t\tResources: []RingResource{{\n\t\t\t\t\tGroupResource: metav1.GroupResource{\n\t\t\t\t\t\tGroup:    \"\",\n\t\t\t\t\t\tResource: \"configmaps\",\n\t\t\t\t\t},\n\t\t\t\t\tControlledResources: []metav1.GroupResource{{\n\t\t\t\t\t\tGroup:    \"\",\n\t\t\t\t\t\tResource: \"secrets\",\n\t\t\t\t\t}},\n\t\t\t\t}},\n\t\t\t},\n\t\t}\n\t})\n\n\tDescribe(\"#LeaseSelector\", func() {\n\t\tIt(\"should return the correct lease selector\", func() {\n\t\t\tExpect(ring.LeaseSelector().String()).To(Equal(\"alpha.sharding.timebertt.dev/controllerring=operator\"))\n\t\t})\n\t})\n\n\tDescribe(\"#LabelShard\", func() {\n\t\tIt(\"should append the ControllerRing name\", func() {\n\t\t\tExpect(ring.LabelShard()).To(Equal(\"shard.alpha.sharding.timebertt.dev/operator\"))\n\t\t})\n\t})\n\n\tDescribe(\"#LabelDrain\", func() {\n\t\tIt(\"should append the ControllerRing name\", func() {\n\t\t\tExpect(ring.LabelDrain()).To(Equal(\"drain.alpha.sharding.timebertt.dev/operator\"))\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/apis/sharding/v1alpha1/v1alpha1_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestV1alpha1(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Sharding API V1alpha1 Suite\")\n}\n"
  },
  {
    "path": "pkg/apis/sharding/v1alpha1/zz_generated.deepcopy.go",
    "content": "//go:build !ignore_autogenerated\n\n/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Code generated by controller-gen. DO NOT EDIT.\n\npackage v1alpha1\n\nimport (\n\t\"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n)\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *ControllerRing) DeepCopyInto(out *ControllerRing) {\n\t*out = *in\n\tout.TypeMeta = in.TypeMeta\n\tin.ObjectMeta.DeepCopyInto(&out.ObjectMeta)\n\tin.Spec.DeepCopyInto(&out.Spec)\n\tin.Status.DeepCopyInto(&out.Status)\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerRing.\nfunc (in *ControllerRing) DeepCopy() *ControllerRing {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(ControllerRing)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.\nfunc (in *ControllerRing) DeepCopyObject() runtime.Object {\n\tif c := in.DeepCopy(); c != nil {\n\t\treturn c\n\t}\n\treturn nil\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *ControllerRingList) DeepCopyInto(out *ControllerRingList) {\n\t*out = *in\n\tout.TypeMeta = in.TypeMeta\n\tin.ListMeta.DeepCopyInto(&out.ListMeta)\n\tif in.Items != nil {\n\t\tin, out := &in.Items, &out.Items\n\t\t*out = make([]ControllerRing, len(*in))\n\t\tfor i := range *in {\n\t\t\t(*in)[i].DeepCopyInto(&(*out)[i])\n\t\t}\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerRingList.\nfunc (in *ControllerRingList) DeepCopy() *ControllerRingList {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(ControllerRingList)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.\nfunc (in *ControllerRingList) DeepCopyObject() runtime.Object {\n\tif c := in.DeepCopy(); c != nil {\n\t\treturn c\n\t}\n\treturn nil\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *ControllerRingSpec) DeepCopyInto(out *ControllerRingSpec) {\n\t*out = *in\n\tif in.Resources != nil {\n\t\tin, out := &in.Resources, &out.Resources\n\t\t*out = make([]RingResource, len(*in))\n\t\tfor i := range *in {\n\t\t\t(*in)[i].DeepCopyInto(&(*out)[i])\n\t\t}\n\t}\n\tif in.NamespaceSelector != nil {\n\t\tin, out := &in.NamespaceSelector, &out.NamespaceSelector\n\t\t*out = new(v1.LabelSelector)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerRingSpec.\nfunc (in *ControllerRingSpec) DeepCopy() *ControllerRingSpec {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(ControllerRingSpec)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *ControllerRingStatus) DeepCopyInto(out *ControllerRingStatus) {\n\t*out = *in\n\tif in.Conditions != nil {\n\t\tin, out := &in.Conditions, &out.Conditions\n\t\t*out = make([]v1.Condition, len(*in))\n\t\tfor i := range *in {\n\t\t\t(*in)[i].DeepCopyInto(&(*out)[i])\n\t\t}\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerRingStatus.\nfunc (in *ControllerRingStatus) DeepCopy() *ControllerRingStatus {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(ControllerRingStatus)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *RingResource) DeepCopyInto(out *RingResource) {\n\t*out = *in\n\tout.GroupResource = in.GroupResource\n\tif in.ControlledResources != nil {\n\t\tin, out := &in.ControlledResources, &out.ControlledResources\n\t\t*out = make([]v1.GroupResource, len(*in))\n\t\tcopy(*out, *in)\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RingResource.\nfunc (in *RingResource) DeepCopy() *RingResource {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(RingResource)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n"
  },
  {
    "path": "pkg/controller/add.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/controller/controllerring\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/controller/sharder\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/controller/shardlease\"\n)\n\n// AddToManager adds all controllers to the manager.\nfunc AddToManager(ctx context.Context, mgr manager.Manager, config *configv1alpha1.SharderConfig) error {\n\tif err := (&controllerring.Reconciler{\n\t\tConfig: config,\n\t}).AddToManager(mgr); err != nil {\n\t\treturn fmt.Errorf(\"failed adding controllerring controller: %w\", err)\n\t}\n\n\tif err := (&sharder.Reconciler{\n\t\tConfig: config,\n\t}).AddToManager(mgr); err != nil {\n\t\treturn fmt.Errorf(\"failed adding sharder controller: %w\", err)\n\t}\n\n\tif err := (&shardlease.Reconciler{}).AddToManager(mgr); err != nil {\n\t\treturn fmt.Errorf(\"failed adding lease controller: %w\", err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/controller/controllerring/add.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controllerring\n\nimport (\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\t\"k8s.io/utils/clock\"\n\t\"sigs.k8s.io/controller-runtime/pkg/builder\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller\"\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\t\"sigs.k8s.io/controller-runtime/pkg/handler\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\tshardinghandler \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/handler\"\n\tshardingpredicate \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/predicate\"\n)\n\n// ControllerName is the name of this controller.\nconst ControllerName = \"controllerring\"\n\n// AddToManager adds Reconciler to the given manager.\nfunc (r *Reconciler) AddToManager(mgr manager.Manager) error {\n\tif r.Client == nil {\n\t\tr.Client = client.WithFieldOwner(mgr.GetClient(), ControllerName+\"-controller\")\n\t}\n\tif r.Recorder == nil {\n\t\tr.Recorder = mgr.GetEventRecorderFor(ControllerName + \"-controller\")\n\t}\n\tif r.Clock == nil {\n\t\tr.Clock = clock.RealClock{}\n\t}\n\n\treturn builder.ControllerManagedBy(mgr).\n\t\tNamed(ControllerName).\n\t\tFor(&shardingv1alpha1.ControllerRing{}, builder.WithPredicates(shardingpredicate.ControllerRingCreatedOrUpdated())).\n\t\tWatches(\n\t\t\t&coordinationv1.Lease{},\n\t\t\thandler.EnqueueRequestsFromMapFunc(shardinghandler.MapLeaseToControllerRing),\n\t\t\tbuilder.WithPredicates(r.LeasePredicate()),\n\t\t).\n\t\tWithOptions(controller.Options{\n\t\t\tMaxConcurrentReconciles: 5,\n\t\t}).\n\t\tComplete(r)\n}\n\nfunc (r *Reconciler) LeasePredicate() predicate.Predicate {\n\treturn predicate.And(\n\t\tshardingpredicate.IsShardLease(),\n\t\tpredicate.Or(\n\t\t\t// react if a shard lease was created or deleted independent of its availability, we want to update\n\t\t\t// ControllerRing.status.shards\n\t\t\tpredicate.Funcs{\n\t\t\t\tCreateFunc: func(_ event.CreateEvent) bool { return true },\n\t\t\t\tUpdateFunc: func(_ event.UpdateEvent) bool { return false },\n\t\t\t\tDeleteFunc: func(_ event.DeleteEvent) bool { return true },\n\t\t\t},\n\t\t\t// for update events, only react if the shard's availability changed\n\t\t\tshardingpredicate.ShardLeaseAvailabilityChanged(r.Clock),\n\t\t),\n\t)\n}\n"
  },
  {
    "path": "pkg/controller/controllerring/add_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controllerring_test\n\nimport (\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/clock/testing\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/controller/controllerring\"\n)\n\nvar _ = Describe(\"Reconciler\", func() {\n\tvar r *Reconciler\n\n\tBeforeEach(func() {\n\t\tr = &Reconciler{}\n\t})\n\n\tDescribe(\"#LeasePredicate\", func() {\n\t\tvar (\n\t\t\tp           predicate.Predicate\n\t\t\tobj, objOld *coordinationv1.Lease\n\n\t\t\tfakeClock *testing.FakePassiveClock\n\t\t)\n\n\t\tBeforeEach(func() {\n\t\t\tfakeClock = testing.NewFakePassiveClock(time.Now())\n\t\t\tr.Clock = fakeClock\n\n\t\t\tp = r.LeasePredicate()\n\n\t\t\tobj = &coordinationv1.Lease{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName: \"foo-0\",\n\t\t\t\t},\n\t\t\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\t\t\tHolderIdentity:       ptr.To(\"foo-0\"),\n\t\t\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-5 * time.Minute))),\n\t\t\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-2 * time.Second))),\n\t\t\t\t},\n\t\t\t}\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"alpha.sharding.timebertt.dev/controllerring\", \"foo\")\n\t\t\tobjOld = obj.DeepCopy()\n\t\t})\n\n\t\tIt(\"should ignore leases with empty label\", func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"alpha.sharding.timebertt.dev/controllerring\", \"\")\n\t\t\tobjOld = obj.DeepCopy()\n\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeFalse())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should react on create events\", func() {\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should react on delete events\", func() {\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should react when shard state changed to available\", func() {\n\t\t\tobjOld.Spec.HolderIdentity = nil\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should react when shard state changed to unavailable\", func() {\n\t\t\tobj.Spec.HolderIdentity = nil\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should ignore when shard state hasn't changed\", func() {\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\n\t\t\tobj.Spec.HolderIdentity = nil\n\t\t\tobjOld.Spec.HolderIdentity = nil\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/controller/controllerring/controllerring_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controllerring_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestControllerRing(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"ControllerRing Controller Suite\")\n}\n"
  },
  {
    "path": "pkg/controller/controllerring/reconciler.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controllerring\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"maps\"\n\t\"strings\"\n\n\t\"github.com/go-logr/logr\"\n\tadmissionregistrationv1 \"k8s.io/api/admissionregistration/v1\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tapiequality \"k8s.io/apimachinery/pkg/api/equality\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\t\"k8s.io/apimachinery/pkg/api/meta\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/client-go/tools/record\"\n\t\"k8s.io/utils/clock\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/webhook/sharder\"\n)\n\n//+kubebuilder:rbac:groups=sharding.timebertt.dev,resources=controllerrings,verbs=get;list;watch\n//+kubebuilder:rbac:groups=sharding.timebertt.dev,resources=controllerrings/status,verbs=update;patch\n//+kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=mutatingwebhookconfigurations,verbs=create;patch\n//+kubebuilder:rbac:groups=\"\",resources=events,verbs=create;patch\n\n// Reconciler reconciles ControllerRings.\ntype Reconciler struct {\n\tClient   client.Client\n\tRecorder record.EventRecorder\n\tClock    clock.PassiveClock\n\tConfig   *configv1alpha1.SharderConfig\n}\n\n// Reconcile reconciles a ControllerRing object.\nfunc (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {\n\tlog := logf.FromContext(ctx)\n\n\tcontrollerRing := &shardingv1alpha1.ControllerRing{}\n\tif err := r.Client.Get(ctx, req.NamespacedName, controllerRing); err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\tlog.V(1).Info(\"Object is gone, stop reconciling\")\n\t\t\treturn reconcile.Result{}, nil\n\t\t}\n\t\treturn reconcile.Result{}, fmt.Errorf(\"error retrieving object from store: %w\", err)\n\t}\n\n\tbefore := controllerRing.DeepCopy()\n\n\t// reconcile sharder webhook configs\n\tif err := r.reconcileWebhooks(ctx, controllerRing); err != nil {\n\t\treturn reconcile.Result{}, r.updateStatusError(ctx, log, fmt.Errorf(\"error reconciling webhooks for ControllerRing: %w\", err), controllerRing, before)\n\t}\n\n\t// collect list of shards in the ring\n\tleaseList := &coordinationv1.LeaseList{}\n\tif err := r.Client.List(ctx, leaseList, client.MatchingLabelsSelector{Selector: controllerRing.LeaseSelector()}); err != nil {\n\t\treturn reconcile.Result{}, r.updateStatusError(ctx, log, fmt.Errorf(\"error listing Leases for ControllerRing: %w\", err), controllerRing, before)\n\t}\n\n\tshards := leases.ToShards(leaseList.Items, r.Clock.Now())\n\tcontrollerRing.Status.Shards = int32(len(shards))                            // nolint:gosec\n\tcontrollerRing.Status.AvailableShards = int32(len(shards.AvailableShards())) // nolint:gosec\n\n\t// update status if necessary\n\treturn reconcile.Result{}, r.updateStatusSuccess(ctx, controllerRing, before)\n}\n\nfunc (r *Reconciler) updateStatusSuccess(ctx context.Context, controllerRing, before *shardingv1alpha1.ControllerRing) error {\n\tif err := r.OptionallyUpdateStatus(ctx, controllerRing, before, func(ready *metav1.Condition) {\n\t\tready.Status = metav1.ConditionTrue\n\t\tready.Reason = \"ReconciliationSucceeded\"\n\t\tready.Message = \"ControllerRing was successfully reconciled\"\n\t}); err != nil {\n\t\treturn fmt.Errorf(\"error updating ControllerRing status: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc (r *Reconciler) updateStatusError(ctx context.Context, log logr.Logger, reconcileError error, controllerRing, before *shardingv1alpha1.ControllerRing) error {\n\tmessage := utils.CapitalizeFirst(reconcileError.Error())\n\n\tr.Recorder.Event(controllerRing, corev1.EventTypeWarning, \"ReconciliationFailed\", message)\n\n\tif err := r.OptionallyUpdateStatus(ctx, controllerRing, before, func(ready *metav1.Condition) {\n\t\tready.Status = metav1.ConditionFalse\n\t\tready.Reason = \"ReconciliationFailed\"\n\t\tready.Message = message\n\t}); err != nil {\n\t\t// We will return the underlying error to the controller. If we fail to publish it to the status, make sure to log\n\t\t// it at least.\n\t\tlog.Error(err, \"Error updating ControllerRing status with error\")\n\t}\n\n\treturn reconcileError\n}\n\nfunc (r *Reconciler) OptionallyUpdateStatus(ctx context.Context, controllerRing, before *shardingv1alpha1.ControllerRing, mutate func(ready *metav1.Condition)) error {\n\t// always update status with the latest observed generation, no matter if reconciliation succeeded or not\n\tcontrollerRing.Status.ObservedGeneration = controllerRing.Generation\n\treadyCondition := metav1.Condition{\n\t\tType:               shardingv1alpha1.ControllerRingReady,\n\t\tObservedGeneration: controllerRing.Generation,\n\t}\n\n\tmutate(&readyCondition)\n\tmeta.SetStatusCondition(&controllerRing.Status.Conditions, readyCondition)\n\n\tif apiequality.Semantic.DeepEqual(controllerRing.Status, before.Status) {\n\t\treturn nil\n\t}\n\n\treturn r.Client.Status().Update(ctx, controllerRing)\n}\n\nfunc (r *Reconciler) reconcileWebhooks(ctx context.Context, controllerRing *shardingv1alpha1.ControllerRing) error {\n\twebhookConfig, err := r.WebhookConfigForControllerRing(controllerRing)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn r.Client.Patch(ctx, webhookConfig, client.Apply)\n}\n\nfunc (r *Reconciler) WebhookConfigForControllerRing(controllerRing *shardingv1alpha1.ControllerRing) (*admissionregistrationv1.MutatingWebhookConfiguration, error) {\n\twebhookConfig := WebhookConfigForControllerRing(controllerRing, r.Config.Webhook.Config)\n\tif err := controllerutil.SetControllerReference(controllerRing, webhookConfig, r.Client.Scheme()); err != nil {\n\t\treturn nil, fmt.Errorf(\"error setting controller reference: %w\", err)\n\t}\n\n\treturn webhookConfig, nil\n}\n\nfunc WebhookConfigForControllerRing(controllerRing *shardingv1alpha1.ControllerRing, config *configv1alpha1.WebhookConfig) *admissionregistrationv1.MutatingWebhookConfiguration {\n\treturn &admissionregistrationv1.MutatingWebhookConfiguration{\n\t\tTypeMeta: metav1.TypeMeta{\n\t\t\tAPIVersion: admissionregistrationv1.SchemeGroupVersion.String(),\n\t\t\tKind:       \"MutatingWebhookConfiguration\",\n\t\t},\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName: \"controllerring-\" + controllerRing.Name,\n\t\t\tLabels: map[string]string{\n\t\t\t\t\"app.kubernetes.io/name\":             shardingv1alpha1.AppControllerSharding,\n\t\t\t\tshardingv1alpha1.LabelControllerRing: controllerRing.Name,\n\t\t\t},\n\t\t\tAnnotations: maps.Clone(config.Annotations),\n\t\t},\n\t\tWebhooks: []admissionregistrationv1.MutatingWebhook{WebhookForControllerRing(controllerRing, config)},\n\t}\n}\n\nfunc WebhookForControllerRing(controllerRing *shardingv1alpha1.ControllerRing, config *configv1alpha1.WebhookConfig) admissionregistrationv1.MutatingWebhook {\n\twebhook := admissionregistrationv1.MutatingWebhook{\n\t\tName:              \"sharder.sharding.timebertt.dev\",\n\t\tClientConfig:      *config.ClientConfig.DeepCopy(),\n\t\tNamespaceSelector: config.NamespaceSelector.DeepCopy(),\n\n\t\t// only process unassigned objects\n\t\tObjectSelector: &metav1.LabelSelector{\n\t\t\tMatchExpressions: []metav1.LabelSelectorRequirement{{\n\t\t\t\tKey:      controllerRing.LabelShard(),\n\t\t\t\tOperator: metav1.LabelSelectorOpDoesNotExist,\n\t\t\t}},\n\t\t},\n\n\t\t// Choose Ignore to trade immediate assignments for minimal disruption, the sharder controller will assign any\n\t\t// objects that missed the sharder webhook.\n\t\tFailurePolicy:           ptr.To(admissionregistrationv1.Ignore),\n\t\tTimeoutSeconds:          ptr.To(int32(5)),\n\t\tSideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNone),\n\t\tAdmissionReviewVersions: []string{\"v1\"},\n\t}\n\n\t// overwrite namespaceSelector with ring-specific namespaceSelector if specified\n\tif controllerRing.Spec.NamespaceSelector != nil {\n\t\twebhook.NamespaceSelector = controllerRing.Spec.NamespaceSelector.DeepCopy()\n\t}\n\n\t// add ring-specific path to webhook client config\n\twebhookPath := sharder.WebhookPathForControllerRing(controllerRing)\n\n\tif service := webhook.ClientConfig.Service; service != nil {\n\t\tservice.Path = ptr.To(webhookPath)\n\t}\n\tif url := webhook.ClientConfig.URL; url != nil {\n\t\t// We can't use path.Join on URLs because it will drop one slash from the scheme.\n\t\t// We accept both URLs with and without trailing slashes, so trim it if present to ensure we have only one as the\n\t\t// path separator.\n\t\t*url = strings.TrimSuffix(*url, \"/\") + webhookPath\n\t}\n\n\t// add rules for all ring resources\n\tfor _, ringResource := range controllerRing.Spec.Resources {\n\t\twebhook.Rules = append(webhook.Rules, RuleForResource(ringResource.GroupResource))\n\n\t\tfor _, controlledResource := range ringResource.ControlledResources {\n\t\t\twebhook.Rules = append(webhook.Rules, RuleForResource(controlledResource))\n\t\t}\n\t}\n\n\treturn webhook\n}\n\n// RuleForResource returns the sharder's webhook rule for the given resource.\nfunc RuleForResource(gr metav1.GroupResource) admissionregistrationv1.RuleWithOperations {\n\treturn admissionregistrationv1.RuleWithOperations{\n\t\tOperations: []admissionregistrationv1.OperationType{\n\t\t\tadmissionregistrationv1.Create,\n\t\t\tadmissionregistrationv1.Update,\n\t\t},\n\t\tRule: admissionregistrationv1.Rule{\n\t\t\tAPIGroups:   []string{gr.Group},\n\t\t\tAPIVersions: []string{\"*\"},\n\t\t\tResources:   []string{gr.Resource},\n\t\t\tScope:       ptr.To(admissionregistrationv1.AllScopes),\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "pkg/controller/controllerring/reconciler_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controllerring_test\n\nimport (\n\t\"context\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\t. \"github.com/onsi/gomega/gstruct\"\n\tadmissionregistrationv1 \"k8s.io/api/admissionregistration/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client/fake\"\n\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/controller/controllerring\"\n)\n\nvar _ = Describe(\"Reconciler\", func() {\n\tvar (\n\t\tctx        context.Context\n\t\tfakeClient client.Client\n\t\tr          *Reconciler\n\n\t\tring   *shardingv1alpha1.ControllerRing\n\t\tconfig *configv1alpha1.SharderConfig\n\t)\n\n\tBeforeEach(func() {\n\t\tctx = context.Background()\n\n\t\tscheme := runtime.NewScheme()\n\t\tExpect(shardingv1alpha1.AddToScheme(scheme)).To(Succeed())\n\t\tExpect(configv1alpha1.AddToScheme(scheme)).To(Succeed())\n\n\t\tring = &shardingv1alpha1.ControllerRing{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tName:       \"foo\",\n\t\t\t\tGeneration: 1,\n\t\t\t},\n\t\t\tStatus: shardingv1alpha1.ControllerRingStatus{\n\t\t\t\tObservedGeneration: 1,\n\t\t\t\tShards:             0,\n\t\t\t\tAvailableShards:    0,\n\t\t\t\tConditions: []metav1.Condition{{\n\t\t\t\t\tType:               \"Ready\",\n\t\t\t\t\tStatus:             metav1.ConditionTrue,\n\t\t\t\t\tObservedGeneration: 1,\n\t\t\t\t}},\n\t\t\t},\n\t\t}\n\n\t\tconfig = &configv1alpha1.SharderConfig{}\n\t\tscheme.Default(config)\n\n\t\tfakeClient = fake.NewClientBuilder().\n\t\t\tWithScheme(scheme).\n\t\t\tWithRuntimeObjects(ring).\n\t\t\tWithStatusSubresource(&shardingv1alpha1.ControllerRing{}).\n\t\t\tBuild()\n\n\t\tr = &Reconciler{\n\t\t\tClient: fakeClient,\n\t\t\tConfig: config,\n\t\t}\n\t})\n\n\tDescribe(\"#OptionallyUpdateStatus\", func() {\n\t\tIt(\"should update status if observed generation is outdated\", func() {\n\t\t\tring.Generation++\n\t\t\tExpect(fakeClient.Update(ctx, ring)).To(Succeed())\n\n\t\t\tExpect(r.OptionallyUpdateStatus(ctx, ring, ring.DeepCopy(), func(ready *metav1.Condition) {})).Should(Succeed())\n\n\t\t\tExpect(fakeClient.Get(ctx, client.ObjectKeyFromObject(ring), ring)).Should(Succeed())\n\t\t\tExpect(ring.Status.ObservedGeneration).Should(Equal(ring.Generation))\n\t\t\tExpect(ring.Status.Conditions[0].ObservedGeneration).Should(Equal(ring.Generation))\n\t\t})\n\n\t\tIt(\"should update status if condition mutated\", func() {\n\t\t\tExpect(r.OptionallyUpdateStatus(ctx, ring, ring.DeepCopy(), func(ready *metav1.Condition) {\n\t\t\t\tready.Status = metav1.ConditionFalse\n\t\t\t})).Should(Succeed())\n\n\t\t\tExpect(fakeClient.Get(ctx, client.ObjectKeyFromObject(ring), ring)).Should(Succeed())\n\t\t\tExpect(ring.Status.Conditions).Should(ConsistOf(MatchFields(IgnoreExtras, Fields{\n\t\t\t\t\"Type\":               Equal(\"Ready\"),\n\t\t\t\t\"Status\":             Equal(metav1.ConditionFalse),\n\t\t\t\t\"ObservedGeneration\": Equal(ring.Generation),\n\t\t\t})))\n\t\t})\n\n\t\tIt(\"should update status if mutated outside the function\", func() {\n\t\t\tbefore := ring.DeepCopy()\n\t\t\tring.Status.AvailableShards = 1\n\n\t\t\tExpect(r.OptionallyUpdateStatus(ctx, ring, before, func(ready *metav1.Condition) {})).Should(Succeed())\n\n\t\t\tExpect(fakeClient.Get(ctx, client.ObjectKeyFromObject(ring), ring)).Should(Succeed())\n\t\t\tExpect(ring.Status.AvailableShards).Should(BeEquivalentTo(1))\n\t\t})\n\n\t\tIt(\"should skip updating status if nothing changed\", func() {\n\t\t\tExpect(fakeClient.Get(ctx, client.ObjectKeyFromObject(ring), ring)).Should(Succeed())\n\t\t\tresourceVersion := ring.ResourceVersion\n\n\t\t\tExpect(r.OptionallyUpdateStatus(ctx, ring, ring.DeepCopy(), func(ready *metav1.Condition) {\n\t\t\t\t*ready = ring.Status.Conditions[0]\n\t\t\t})).Should(Succeed())\n\n\t\t\tExpect(fakeClient.Get(ctx, client.ObjectKeyFromObject(ring), ring)).Should(Succeed())\n\t\t\tExpect(ring.ResourceVersion).Should(Equal(resourceVersion))\n\t\t})\n\t})\n\n\tDescribe(\"#WebhookConfigForControllerRing\", func() {\n\t\tIt(\"should have the correct metadata\", func() {\n\t\t\tExpect(r.WebhookConfigForControllerRing(ring)).To(PointTo(MatchFields(IgnoreExtras, Fields{\n\t\t\t\t\"ObjectMeta\": MatchFields(IgnoreExtras, Fields{\n\t\t\t\t\t\"Name\": Equal(\"controllerring-\" + ring.Name),\n\t\t\t\t\t\"Labels\": Equal(map[string]string{\n\t\t\t\t\t\t\"app.kubernetes.io/name\":                      \"controller-sharding\",\n\t\t\t\t\t\t\"alpha.sharding.timebertt.dev/controllerring\": ring.Name,\n\t\t\t\t\t}),\n\t\t\t\t}),\n\t\t\t})))\n\t\t})\n\n\t\tIt(\"should copy the config's annotations\", func() {\n\t\t\tconfig.Webhook.Config.Annotations = map[string]string{\n\t\t\t\t\"my\": \"annotation\",\n\t\t\t}\n\n\t\t\tExpect(r.WebhookConfigForControllerRing(ring)).To(PointTo(\n\t\t\t\tHaveField(\"ObjectMeta.Annotations\", Equal(map[string]string{\n\t\t\t\t\t\"my\": \"annotation\",\n\t\t\t\t})),\n\t\t\t))\n\t\t})\n\n\t\tIt(\"should set the controller reference\", func() {\n\t\t\tring.UID = \"123456\"\n\n\t\t\tExpect(r.WebhookConfigForControllerRing(ring)).To(PointTo(\n\t\t\t\tHaveField(\"ObjectMeta.OwnerReferences\", ConsistOf(metav1.OwnerReference{\n\t\t\t\t\tAPIVersion:         \"sharding.timebertt.dev/v1alpha1\",\n\t\t\t\t\tKind:               \"ControllerRing\",\n\t\t\t\t\tName:               ring.Name,\n\t\t\t\t\tUID:                ring.UID,\n\t\t\t\t\tController:         ptr.To(true),\n\t\t\t\t\tBlockOwnerDeletion: ptr.To(true),\n\t\t\t\t})),\n\t\t\t))\n\t\t})\n\n\t\tIt(\"should have a single webhook\", func() {\n\t\t\tExpect(r.WebhookConfigForControllerRing(ring)).To(HaveField(\"Webhooks\", HaveLen(1)))\n\t\t})\n\t})\n\n\tDescribe(\"#WebhookForControllerRing\", func() {\n\t\tIt(\"should have the correct settings\", func() {\n\t\t\tExpect(WebhookForControllerRing(ring, config.Webhook.Config)).To(MatchFields(IgnoreExtras, Fields{\n\t\t\t\t\"Name\":                    Equal(\"sharder.sharding.timebertt.dev\"),\n\t\t\t\t\"SideEffects\":             PointTo(Equal(admissionregistrationv1.SideEffectClassNone)),\n\t\t\t\t\"AdmissionReviewVersions\": ConsistOf(\"v1\"),\n\t\t\t}))\n\t\t})\n\n\t\tIt(\"should have non-problematic failure settings\", func() {\n\t\t\tExpect(WebhookForControllerRing(ring, config.Webhook.Config)).To(MatchFields(IgnoreExtras, Fields{\n\t\t\t\t\"FailurePolicy\":  PointTo(Equal(admissionregistrationv1.Ignore)),\n\t\t\t\t\"TimeoutSeconds\": PointTo(BeEquivalentTo(5)),\n\t\t\t}))\n\t\t})\n\n\t\tContext(\"client config\", func() {\n\t\t\tIt(\"should use the config's default client config and add the path\", func() {\n\t\t\t\tExpect(WebhookForControllerRing(ring, config.Webhook.Config).ClientConfig).To(Equal(admissionregistrationv1.WebhookClientConfig{\n\t\t\t\t\tService: &admissionregistrationv1.ServiceReference{\n\t\t\t\t\t\tNamespace: \"sharding-system\",\n\t\t\t\t\t\tName:      \"sharder\",\n\t\t\t\t\t\tPath:      ptr.To(\"/webhooks/sharder/controllerring/foo\"),\n\t\t\t\t\t},\n\t\t\t\t}))\n\t\t\t})\n\n\t\t\tIt(\"should use the service client config and add the path\", func() {\n\t\t\t\tconfig.Webhook.Config.ClientConfig = &admissionregistrationv1.WebhookClientConfig{\n\t\t\t\t\tService: &admissionregistrationv1.ServiceReference{\n\t\t\t\t\t\tNamespace: \"default\",\n\t\t\t\t\t\tName:      \"webhook-service\",\n\t\t\t\t\t\tPort:      ptr.To[int32](8080),\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\tclientConfig := config.Webhook.Config.ClientConfig.DeepCopy()\n\n\t\t\t\tExpect(WebhookForControllerRing(ring, config.Webhook.Config).ClientConfig).To(Equal(admissionregistrationv1.WebhookClientConfig{\n\t\t\t\t\tService: &admissionregistrationv1.ServiceReference{\n\t\t\t\t\t\tNamespace: clientConfig.Service.Namespace,\n\t\t\t\t\t\tName:      clientConfig.Service.Name,\n\t\t\t\t\t\tPort:      clientConfig.Service.Port,\n\t\t\t\t\t\tPath:      ptr.To(\"/webhooks/sharder/controllerring/foo\"),\n\t\t\t\t\t},\n\t\t\t\t}))\n\t\t\t})\n\n\t\t\tIt(\"should use the URL client config and add the path\", func() {\n\t\t\t\tconfig.Webhook.Config.ClientConfig = &admissionregistrationv1.WebhookClientConfig{\n\t\t\t\t\tURL: ptr.To(\"https://example.com/webhook\"),\n\t\t\t\t}\n\n\t\t\t\tExpect(WebhookForControllerRing(ring, config.Webhook.Config).ClientConfig).To(Equal(admissionregistrationv1.WebhookClientConfig{\n\t\t\t\t\tURL: ptr.To(\"https://example.com/webhook/webhooks/sharder/controllerring/foo\"),\n\t\t\t\t}))\n\t\t\t})\n\n\t\t\tIt(\"should use the URL client config with a trailing slash and add the path\", func() {\n\t\t\t\tconfig.Webhook.Config.ClientConfig = &admissionregistrationv1.WebhookClientConfig{\n\t\t\t\t\tURL: ptr.To(\"https://example.com/\"),\n\t\t\t\t}\n\n\t\t\t\tExpect(WebhookForControllerRing(ring, config.Webhook.Config).ClientConfig).To(Equal(admissionregistrationv1.WebhookClientConfig{\n\t\t\t\t\tURL: ptr.To(\"https://example.com/webhooks/sharder/controllerring/foo\"),\n\t\t\t\t}))\n\t\t\t})\n\t\t})\n\n\t\tContext(\"namespace selector\", func() {\n\t\t\tIt(\"should use the config's default namespace selector\", func() {\n\t\t\t\tExpect(WebhookForControllerRing(ring, config.Webhook.Config).NamespaceSelector).To(Equal(&metav1.LabelSelector{\n\t\t\t\t\tMatchExpressions: []metav1.LabelSelectorRequirement{{\n\t\t\t\t\t\tKey:      corev1.LabelMetadataName,\n\t\t\t\t\t\tOperator: metav1.LabelSelectorOpNotIn,\n\t\t\t\t\t\tValues:   []string{\"kube-system\", \"sharding-system\"},\n\t\t\t\t\t}},\n\t\t\t\t}))\n\t\t\t})\n\n\t\t\tIt(\"should use the config's namespace selector\", func() {\n\t\t\t\tconfig.Webhook.Config.NamespaceSelector = &metav1.LabelSelector{\n\t\t\t\t\tMatchLabels: map[string]string{\"my\": \"label\"},\n\t\t\t\t}\n\t\t\t\tnamespaceSelector := config.Webhook.Config.NamespaceSelector.DeepCopy()\n\n\t\t\t\tExpect(WebhookForControllerRing(ring, config.Webhook.Config).NamespaceSelector).To(Equal(namespaceSelector))\n\t\t\t})\n\n\t\t\tIt(\"should use the ControllerRing's namespace selector\", func() {\n\t\t\t\tring.Spec.NamespaceSelector = &metav1.LabelSelector{\n\t\t\t\t\tMatchLabels: map[string]string{\"my\": \"label\"},\n\t\t\t\t}\n\t\t\t\tnamespaceSelector := ring.Spec.NamespaceSelector.DeepCopy()\n\n\t\t\t\tExpect(WebhookForControllerRing(ring, config.Webhook.Config).NamespaceSelector).To(Equal(namespaceSelector))\n\t\t\t})\n\t\t})\n\n\t\tIt(\"should only select unassigned objects\", func() {\n\t\t\tselector, err := metav1.LabelSelectorAsSelector(WebhookForControllerRing(ring, config.Webhook.Config).ObjectSelector)\n\t\t\tExpect(err).NotTo(HaveOccurred())\n\n\t\t\tExpect(selector.Matches(labels.Set{})).To(BeTrue())\n\t\t\tExpect(selector.Matches(labels.Set{ring.LabelShard(): \"shard-1\"})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should add rules for all resources\", func() {\n\t\t\tring.Spec.Resources = []shardingv1alpha1.RingResource{\n\t\t\t\t{\n\t\t\t\t\tGroupResource: metav1.GroupResource{Group: \"\", Resource: \"configmaps\"},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tGroupResource:       metav1.GroupResource{Group: \"apps\", Resource: \"deployments\"},\n\t\t\t\t\tControlledResources: []metav1.GroupResource{{Group: \"apps\", Resource: \"replicasets\"}},\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tExpect(WebhookForControllerRing(ring, config.Webhook.Config).Rules).To(ConsistOf(\n\t\t\t\tRuleForResource(ring.Spec.Resources[0].GroupResource),\n\t\t\t\tRuleForResource(ring.Spec.Resources[1].GroupResource),\n\t\t\t\tRuleForResource(ring.Spec.Resources[1].ControlledResources[0]),\n\t\t\t))\n\t\t})\n\t})\n\n\tDescribe(\"#RuleForResource\", func() {\n\t\tvar gr metav1.GroupResource\n\n\t\tBeforeEach(func() {\n\t\t\tgr.Group = \"apps\"\n\t\t\tgr.Resource = \"deployments\"\n\t\t})\n\n\t\tIt(\"should act on Create and Update\", func() {\n\t\t\tExpect(RuleForResource(gr).Operations).To(ConsistOf(admissionregistrationv1.Create, admissionregistrationv1.Update))\n\t\t})\n\n\t\tIt(\"should generate a matching rule\", func() {\n\t\t\tExpect(RuleForResource(gr).Rule).To(Equal(admissionregistrationv1.Rule{\n\t\t\t\tAPIGroups:   []string{\"apps\"},\n\t\t\t\tAPIVersions: []string{\"*\"},\n\t\t\t\tResources:   []string{\"deployments\"},\n\t\t\t\tScope:       ptr.To(admissionregistrationv1.AllScopes),\n\t\t\t}))\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/controller/sharder/add.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder\n\nimport (\n\t\"time\"\n\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\t\"k8s.io/client-go/util/workqueue\"\n\t\"k8s.io/utils/clock\"\n\t\"sigs.k8s.io/controller-runtime/pkg/builder\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller\"\n\t\"sigs.k8s.io/controller-runtime/pkg/handler\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\tshardinghandler \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/handler\"\n\tshardingpredicate \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/predicate\"\n)\n\n// ControllerName is the name of this controller.\nconst ControllerName = \"sharder\"\n\n// AddToManager adds Reconciler to the given manager.\nfunc (r *Reconciler) AddToManager(mgr manager.Manager) error {\n\tif r.Client == nil {\n\t\tr.Client = mgr.GetClient()\n\t}\n\tif r.Reader == nil {\n\t\tr.Reader = mgr.GetAPIReader()\n\t}\n\tif r.Clock == nil {\n\t\tr.Clock = clock.RealClock{}\n\t}\n\n\treturn builder.ControllerManagedBy(mgr).\n\t\tNamed(ControllerName).\n\t\tFor(&shardingv1alpha1.ControllerRing{}, builder.WithPredicates(shardingpredicate.ControllerRingCreatedOrUpdated())).\n\t\tWatches(\n\t\t\t&coordinationv1.Lease{},\n\t\t\thandler.EnqueueRequestsFromMapFunc(shardinghandler.MapLeaseToControllerRing),\n\t\t\tbuilder.WithPredicates(r.LeasePredicate()),\n\t\t).\n\t\tWithOptions(controller.Options{\n\t\t\tMaxConcurrentReconciles: 5,\n\t\t\t// This custom rate limiter differs from the default in these aspects:\n\t\t\t// - no overall rate limiting, only per-item rate limiting\n\t\t\t// - start at 5s base delay, faster retries are probably wasted load on the API server\n\t\t\t// - cap delay at the configured sync period\n\t\t\tRateLimiter: workqueue.NewTypedItemExponentialFailureRateLimiter[reconcile.Request](5*time.Second, r.Config.Controller.Sharder.SyncPeriod.Duration),\n\t\t}).\n\t\tComplete(r)\n}\n\nfunc (r *Reconciler) LeasePredicate() predicate.Predicate {\n\treturn predicate.And(\n\t\tshardingpredicate.IsShardLease(),\n\t\tshardingpredicate.ShardLeaseAvailabilityChanged(r.Clock),\n\t)\n}\n"
  },
  {
    "path": "pkg/controller/sharder/reconciler.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n\t\"github.com/hashicorp/go-multierror\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"k8s.io/apimachinery/pkg/util/wait\"\n\t\"k8s.io/utils/clock\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\tshardingmetrics \"github.com/timebertt/kubernetes-controller-sharding/pkg/metrics\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/consistenthash\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/key\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/ring\"\n\tutilclient \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/client\"\n\tutilerrors \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/errors\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/pager\"\n)\n\n//+kubebuilder:rbac:groups=sharding.timebertt.dev,resources=controllerrings,verbs=get;list;watch\n//+kubebuilder:rbac:groups=\"\",resources=namespaces,verbs=get;list;watch\n\n// Note: The sharder requires permissions to list and patch resources listed in ControllerRings. However, the default\n// sharder role doesn't include permissions for listing/mutating arbitrary resources (which would basically be\n// cluster-admin access) to adhere to the least privilege principle.\n// We can't automate permission management in the controllerring controller, because you can't grant permissions you don't\n// already have.\n// Hence, users need to grant the sharder permissions for listing/mutating sharded resources explicitly.\n\n// Reconciler reconciles ControllerRings.\ntype Reconciler struct {\n\tClient client.Client\n\tReader client.Reader\n\tClock  clock.PassiveClock\n\tConfig *configv1alpha1.SharderConfig\n}\n\n// Reconcile reconciles a ControllerRing object.\nfunc (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {\n\tlog := logf.FromContext(ctx)\n\n\tcontrollerRing := &shardingv1alpha1.ControllerRing{}\n\tif err := r.Client.Get(ctx, req.NamespacedName, controllerRing); err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\tlog.V(1).Info(\"Object is gone, stop reconciling\")\n\t\t\treturn reconcile.Result{}, nil\n\t\t}\n\t\treturn reconcile.Result{}, fmt.Errorf(\"error retrieving object from store: %w\", err)\n\t}\n\n\to, err := r.NewOperation(ctx, controllerRing)\n\tif err != nil {\n\t\treturn reconcile.Result{}, err\n\t}\n\n\tlog.Info(\"Starting resync of object assignments for ControllerRing\")\n\tdefer func(start time.Time) {\n\t\tlog.Info(\"Finished resync of object assignments for ControllerRing\", \"duration\", r.Clock.Since(start))\n\t}(r.Clock.Now())\n\n\tif err := o.ResyncControllerRing(ctx, log); err != nil {\n\t\treturn reconcile.Result{}, err\n\t}\n\n\t// requeue for periodic resync\n\treturn reconcile.Result{RequeueAfter: r.Config.Controller.Sharder.SyncPeriod.Duration}, nil\n}\n\nfunc (r *Reconciler) NewOperation(ctx context.Context, controllerRing *shardingv1alpha1.ControllerRing) (*Operation, error) {\n\t// collect list of shards in the ring\n\tleaseList := &coordinationv1.LeaseList{}\n\tif err := r.Client.List(ctx, leaseList, client.MatchingLabelsSelector{Selector: controllerRing.LeaseSelector()}); err != nil {\n\t\treturn nil, fmt.Errorf(\"error listing Leases for ControllerRing: %w\", err)\n\t}\n\n\t// get ring and shards from cache\n\thashRing, shards := ring.FromLeases(controllerRing, leaseList, r.Clock.Now())\n\n\tnamespaces, err := r.GetSelectedNamespaces(ctx, controllerRing)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &Operation{\n\t\tClient:         r.Client,\n\t\tReader:         r.Reader,\n\t\tControllerRing: controllerRing,\n\t\tNamespaces:     namespaces,\n\t\tHashRing:       hashRing,\n\t\tShards:         shards,\n\t\tConcurrency:    int(*r.Config.Controller.Sharder.ConcurrentMoves),\n\t}, nil\n}\n\nfunc (r *Reconciler) GetSelectedNamespaces(ctx context.Context, controllerRing *shardingv1alpha1.ControllerRing) (sets.Set[string], error) {\n\tnamespaceSelector := r.Config.Webhook.Config.NamespaceSelector\n\tif controllerRing.Spec.NamespaceSelector != nil {\n\t\tnamespaceSelector = controllerRing.Spec.NamespaceSelector\n\t}\n\n\tselector, err := metav1.LabelSelectorAsSelector(namespaceSelector)\n\tif err != nil {\n\t\treturn nil, reconcile.TerminalError(err)\n\t}\n\n\tnamespaceList := &corev1.NamespaceList{}\n\tif err := r.Client.List(ctx, namespaceList, client.MatchingLabelsSelector{Selector: selector}); err != nil {\n\t\treturn nil, fmt.Errorf(\"error listing selected namespaces for ControllerRing: %w\", err)\n\t}\n\n\tnamespaceSet := sets.New[string]()\n\tfor _, namespace := range namespaceList.Items {\n\t\tnamespaceSet.Insert(namespace.Name)\n\t}\n\n\treturn namespaceSet, err\n}\n\ntype Operation struct {\n\tClient client.Client\n\tReader client.Reader\n\n\tControllerRing *shardingv1alpha1.ControllerRing\n\tNamespaces     sets.Set[string]\n\tHashRing       *consistenthash.Ring\n\tShards         leases.Shards\n\n\tConcurrency int\n}\n\ntype workItem struct {\n\tdrain           bool\n\tgr              metav1.GroupResource\n\tgvk             schema.GroupVersionKind\n\tkey             client.ObjectKey\n\tresourceVersion string\n\tcurrentShard    string\n}\n\nfunc (o *Operation) ResyncControllerRing(ctx context.Context, log logr.Logger) error {\n\tvar (\n\t\twg   wait.Group\n\t\terrs = make(chan error)\n\t\twork = make(chan *workItem, o.Concurrency)\n\t)\n\n\t// Compile all objects that need to be moved or drained, and add them to the queue.\n\t// The buffer limit of the queue applies backpressure on the work generator (throttling list paging as needed).\n\twg.Start(func() {\n\t\to.compileWorkItemsForRing(ctx, work, errs)\n\t\tclose(work)\n\t})\n\n\t// read work items from the queue and perform drains/movements with the configured concurrency\n\tfor i := 0; i < o.Concurrency; i++ {\n\t\twg.Start(func() {\n\t\t\tfor o.processNextWorkItem(ctx, log, work, errs) {\n\t\t\t}\n\t\t})\n\t}\n\n\t// wait for all processors, then stop collecting errors\n\tgo func() {\n\t\twg.Wait()\n\t\tclose(errs)\n\t}()\n\n\t// collect all errors and return a combined error if any occurred\n\tallErrs := &multierror.Error{ErrorFormat: utilerrors.FormatErrors}\n\tfor err := range errs {\n\t\tallErrs = multierror.Append(allErrs, err)\n\t}\n\n\treturn allErrs.ErrorOrNil()\n}\n\nfunc (o *Operation) compileWorkItemsForRing(ctx context.Context, work chan<- *workItem, errs chan<- error) {\n\t// check all ring resources\n\tfor _, ringResource := range o.ControllerRing.Spec.Resources {\n\t\terrs <- o.compileWorkItemsForResource(ctx, ringResource.GroupResource, false, work)\n\n\t\tfor _, controlledResource := range ringResource.ControlledResources {\n\t\t\terrs <- o.compileWorkItemsForResource(ctx, controlledResource, true, work)\n\t\t}\n\t}\n}\n\nfunc (o *Operation) compileWorkItemsForResource(\n\tctx context.Context,\n\tgr metav1.GroupResource,\n\tcontrolled bool,\n\twork chan<- *workItem,\n) error {\n\tgvks, err := o.Client.RESTMapper().KindsFor(schema.GroupVersionResource{Group: gr.Group, Resource: gr.Resource})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error determining kinds for resource %q: %w\", gr.String(), err)\n\t}\n\tif len(gvks) == 0 {\n\t\treturn fmt.Errorf(\"no kinds found for resource %q\", gr.String())\n\t}\n\n\tvar allErrs *multierror.Error\n\n\tlist := &metav1.PartialObjectMetadataList{}\n\tlist.SetGroupVersionKind(gvks[0])\n\terr = pager.New(o.Reader).EachListItemWithAlloc(ctx, list,\n\t\tfunc(obj client.Object) error {\n\t\t\tif !o.Namespaces.Has(obj.GetNamespace()) {\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tif w, err := o.workItemForObject(gr, controlled, obj.(*metav1.PartialObjectMetadata)); err != nil {\n\t\t\t\tallErrs = multierror.Append(allErrs, err)\n\t\t\t} else if w != nil {\n\t\t\t\twork <- w\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t\t// List a recent version from the API server's watch cache by setting resourceVersion=0. This reduces the load on etcd\n\t\t// for ring resyncs. Listing from etcd with quorum read would be a scalability limitation/bottleneck.\n\t\t// If we try to move or drain an object with an old resourceVersion (conflict error), we will retry with exponential\n\t\t// backoff.\n\t\t// This trades retries for smaller impact of periodic resyncs (that don't require any action).\n\t\tutilclient.ResourceVersion(\"0\"),\n\t)\n\tif err != nil {\n\t\tallErrs = multierror.Append(allErrs, fmt.Errorf(\"error listing %s: %w\", gr.String(), err))\n\t}\n\n\treturn allErrs.ErrorOrNil()\n}\n\nvar (\n\t// KeyForObject is an alias for key.ForObject, exposed for testing.\n\tKeyForObject = key.ForObject\n\t// KeyForController is an alias for key.ForController, exposed for testing.\n\tKeyForController = key.ForController\n)\n\nfunc (o *Operation) workItemForObject(\n\tgr metav1.GroupResource,\n\tcontrolled bool,\n\tobj *metav1.PartialObjectMetadata,\n) (*workItem, error) {\n\tkeyFunc := KeyForObject\n\tif controlled {\n\t\tkeyFunc = KeyForController\n\t}\n\n\thashKey, err := keyFunc(obj)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif hashKey == \"\" {\n\t\t// object should not be assigned\n\t\treturn nil, nil\n\t}\n\n\tvar (\n\t\tdesiredShard = o.HashRing.Hash(hashKey)\n\t\tcurrentShard = obj.Labels[o.ControllerRing.LabelShard()]\n\t)\n\n\tif desiredShard == \"\" {\n\t\t// if no shard is available, there's nothing we can do\n\t\treturn nil, nil\n\t}\n\n\tif desiredShard == currentShard {\n\t\t// object is correctly assigned, nothing to do here\n\t\treturn nil, nil\n\t}\n\n\tw := &workItem{\n\t\tgr:              gr,\n\t\tgvk:             obj.GroupVersionKind(),\n\t\tkey:             client.ObjectKeyFromObject(obj),\n\t\tresourceVersion: obj.ResourceVersion,\n\t\tcurrentShard:    currentShard,\n\t}\n\n\tif currentShard != \"\" && o.Shards.ByID(currentShard).State.IsAvailable() && !controlled {\n\t\t// If the object should be moved and the current shard is still available, we need to drain it.\n\t\t// We only drain non-controlled objects, the controller's main object is used as a synchronization point for\n\t\t// preventing concurrent reconciliations.\n\t\tw.drain = true\n\t}\n\n\t// At this point, the object is either unassigned or the current shard is not available.\n\t// We send a (potentially empty) patch to trigger an assignment by the sharder webhook.\n\treturn w, nil\n}\n\nfunc (o *Operation) processNextWorkItem(\n\tctx context.Context,\n\tlog logr.Logger,\n\twork <-chan *workItem,\n\terrs chan<- error,\n) bool {\n\tselect {\n\tcase <-ctx.Done():\n\t\t// stop when context is canceled\n\t\treturn false\n\tcase w, ok := <-work:\n\t\tif !ok {\n\t\t\t// stop when work queue is closed (all items have been processed)\n\t\t\treturn false\n\t\t}\n\n\t\tobj := &metav1.PartialObjectMetadata{}\n\t\tobj.SetGroupVersionKind(w.gvk)\n\t\tobj.SetName(w.key.Name)\n\t\tobj.SetNamespace(w.key.Namespace)\n\t\tobj.SetResourceVersion(w.resourceVersion)\n\n\t\tlog = log.WithValues(\"resource\", w.gr, \"object\", w.key)\n\t\tif w.drain {\n\t\t\tlog.V(1).Info(\"Draining object from shard\", \"currentShard\", w.currentShard)\n\t\t\terrs <- o.drainObject(ctx, obj, w.gr)\n\t\t} else {\n\t\t\tlog.V(1).Info(\"Moving object\")\n\t\t\terrs <- o.moveObject(ctx, obj, w.gr)\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc (o *Operation) drainObject(\n\tctx context.Context,\n\tobj *metav1.PartialObjectMetadata,\n\tgr metav1.GroupResource,\n) error {\n\tpatch := fmt.Sprintf(\n\t\t// - use optimistic locking by including the object's current resourceVersion\n\t\t// - add drain label; object will go through the sharder webhook when shard removes the drain label, which will\n\t\t//   perform the assignment\n\t\t`{\"metadata\":{\"resourceVersion\":\"%s\",\"labels\":{\"%s\":\"true\"}}}`,\n\t\tobj.ResourceVersion, o.ControllerRing.LabelDrain(),\n\t)\n\n\tif err := o.Client.Patch(ctx, obj, client.RawPatch(types.MergePatchType, []byte(patch))); err != nil {\n\t\treturn fmt.Errorf(\"error draining %s %q: %w\", gr.String(), client.ObjectKeyFromObject(obj), err)\n\t}\n\n\tshardingmetrics.DrainsTotal.WithLabelValues(\n\t\to.ControllerRing.Name, gr.Group, gr.Resource,\n\t).Inc()\n\n\treturn nil\n}\n\nfunc (o *Operation) moveObject(\n\tctx context.Context,\n\tobj *metav1.PartialObjectMetadata,\n\tgr metav1.GroupResource,\n) error {\n\tpatch := fmt.Sprintf(\n\t\t// - use optimistic locking by including the object's current resourceVersion\n\t\t// - remove shard label\n\t\t// - remove drain label if it is still present, this might happen when trying to drain an object from a shard that\n\t\t//   just got unavailable\n\t\t`{\"metadata\":{\"resourceVersion\":\"%s\",\"labels\":{\"%s\":null,\"%s\":null}}}`,\n\t\tobj.ResourceVersion, o.ControllerRing.LabelShard(), o.ControllerRing.LabelDrain(),\n\t)\n\n\tif err := o.Client.Patch(ctx, obj, client.RawPatch(types.MergePatchType, []byte(patch))); err != nil {\n\t\treturn fmt.Errorf(\"error moving %s %q: %w\", gr.String(), client.ObjectKeyFromObject(obj), err)\n\t}\n\n\tshardingmetrics.MovementsTotal.WithLabelValues(\n\t\to.ControllerRing.Name, gr.Group, gr.Resource,\n\t).Inc()\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/controller/sharder/reconciler_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder_test\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/clock/testing\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client/fake\"\n\t. \"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/controller/sharder\"\n\tutilclient \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/client\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n)\n\nvar (\n\tctx        context.Context\n\tclock      *testing.FakePassiveClock\n\tfakeClient client.Client\n\tr          *Reconciler\n\n\tcontrollerRing *shardingv1alpha1.ControllerRing\n\tconfig         *configv1alpha1.SharderConfig\n\n\tnamespace *corev1.Namespace\n\n\tavailableShard *coordinationv1.Lease\n)\n\nvar _ = BeforeEach(func() {\n\tctx = context.Background()\n\tclock = testing.NewFakePassiveClock(time.Now())\n\n\tnamespace = newNamespace(\"test\")\n\n\tcontrollerRing = &shardingv1alpha1.ControllerRing{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName: \"foo\",\n\t\t},\n\t\tSpec: shardingv1alpha1.ControllerRingSpec{\n\t\t\tResources: []shardingv1alpha1.RingResource{{\n\t\t\t\tGroupResource: metav1.GroupResource{\n\t\t\t\t\tResource: \"secrets\",\n\t\t\t\t},\n\t\t\t\tControlledResources: []metav1.GroupResource{{\n\t\t\t\t\tResource: \"configmaps\",\n\t\t\t\t}},\n\t\t\t}},\n\t\t\tNamespaceSelector: &metav1.LabelSelector{\n\t\t\t\tMatchExpressions: []metav1.LabelSelectorRequirement{{\n\t\t\t\t\tKey:      corev1.LabelMetadataName,\n\t\t\t\t\tOperator: metav1.LabelSelectorOpIn,\n\t\t\t\t\tValues:   []string{namespace.Name},\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t}\n\n\tavailableShard = newLease()\n\n\tfakeClient = fake.NewClientBuilder().\n\t\tWithScheme(utilclient.SharderScheme).\n\t\tWithObjects(controllerRing, namespace, availableShard).\n\t\tBuild()\n\tSetClient(fakeClient)\n\n\tconfig = &configv1alpha1.SharderConfig{}\n\tutilclient.SharderScheme.Default(config)\n\n\tr = &Reconciler{\n\t\tClient: fakeClient,\n\t\tReader: fakeClient,\n\t\tClock:  clock,\n\t\tConfig: config,\n\t}\n})\n\nvar _ = Describe(\"#GetSelectedNamespaces\", func() {\n\tBeforeEach(func() {\n\t\tExpect(fakeClient.Create(ctx, newNamespace(\"other\"))).To(Succeed())\n\t\tExpect(fakeClient.Create(ctx, newNamespace(metav1.NamespaceSystem))).To(Succeed())\n\t\tExpect(fakeClient.Create(ctx, newNamespace(shardingv1alpha1.NamespaceSystem))).To(Succeed())\n\t})\n\n\tIt(\"should return all matching namespaces\", func() {\n\t\tnamespaces, err := r.GetSelectedNamespaces(ctx, controllerRing)\n\t\tExpect(err).NotTo(HaveOccurred())\n\t\tExpect(namespaces.UnsortedList()).To(ConsistOf(\"test\"))\n\t})\n\n\tWhen(\"the ControllerRing's namespace selector is unset\", func() {\n\t\tBeforeEach(func() {\n\t\t\tcontrollerRing.Spec.NamespaceSelector = nil\n\t\t})\n\n\t\tIt(\"should use the config's namespace selector\", func() {\n\t\t\tnamespaces, err := r.GetSelectedNamespaces(ctx, controllerRing)\n\t\t\tExpect(err).NotTo(HaveOccurred())\n\t\t\tExpect(namespaces.UnsortedList()).To(ConsistOf(\"test\", \"other\"))\n\t\t})\n\t})\n\n\tWhen(\"the ControllerRing's namespace selector is invalid\", func() {\n\t\tBeforeEach(func() {\n\t\t\tcontrollerRing.Spec.NamespaceSelector.MatchExpressions[0].Operator = \"invalid\"\n\t\t})\n\n\t\tIt(\"should return a terminal error\", func() {\n\t\t\tExpect(r.GetSelectedNamespaces(ctx, controllerRing)).Error().To(MatchError(reconcile.TerminalError(nil)))\n\t\t})\n\t})\n})\n\nvar _ = Describe(\"#NewOperation\", func() {\n\tvar deadShard *coordinationv1.Lease\n\n\tBeforeEach(func() {\n\t\tdeadShard = newLease()\n\t\tdeadShard.Spec.HolderIdentity = nil\n\t\tExpect(fakeClient.Create(ctx, deadShard)).To(Succeed())\n\t})\n\n\tIt(\"should collect the shard leases\", func() {\n\t\to, err := r.NewOperation(ctx, controllerRing)\n\t\tExpect(err).NotTo(HaveOccurred())\n\n\t\tExpect(o.Shards.IDs()).To(ConsistOf(availableShard.Name, deadShard.Name))\n\t\tExpect(o.Shards.ByID(availableShard.Name).State.IsAvailable()).To(BeTrue())\n\t\tExpect(o.Shards.ByID(deadShard.Name).State.IsAvailable()).To(BeFalse())\n\t})\n\n\tIt(\"should construct a hash ring\", func() {\n\t\to, err := r.NewOperation(ctx, controllerRing)\n\t\tExpect(err).NotTo(HaveOccurred())\n\n\t\tExpect(o.HashRing.Hash(\"foo\")).To(Equal(availableShard.Name))\n\t})\n\n\tIt(\"should collect all matching namespaces\", func() {\n\t\to, err := r.NewOperation(ctx, controllerRing)\n\t\tExpect(err).NotTo(HaveOccurred())\n\n\t\tExpect(o.Namespaces.UnsortedList()).To(ConsistOf(\"test\"))\n\t})\n})\n\nfunc newNamespace(name string) *corev1.Namespace {\n\treturn &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{\n\t\tName:   name,\n\t\tLabels: map[string]string{corev1.LabelMetadataName: name},\n\t}}\n}\n\nfunc newLease() *coordinationv1.Lease {\n\tname := \"shard-\" + test.RandomSuffix()\n\n\treturn &coordinationv1.Lease{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      name,\n\t\t\tNamespace: namespace.Namespace,\n\t\t\tLabels: map[string]string{\n\t\t\t\tshardingv1alpha1.LabelControllerRing: controllerRing.Name,\n\t\t\t},\n\t\t},\n\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\tHolderIdentity:       ptr.To(name),\n\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(clock.Now().Add(-5 * time.Minute))),\n\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(clock.Now().Add(-2 * time.Second))),\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "pkg/controller/sharder/sharder_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestSharder(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Sharder Controller Suite\")\n}\n"
  },
  {
    "path": "pkg/controller/shardlease/add.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage shardlease\n\nimport (\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\t\"k8s.io/client-go/util/workqueue\"\n\t\"k8s.io/utils/clock\"\n\t\"sigs.k8s.io/controller-runtime/pkg/builder\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller\"\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\t\"sigs.k8s.io/controller-runtime/pkg/handler\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\tshardinghandler \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/handler\"\n\tshardingpredicate \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/predicate\"\n)\n\n// ControllerName is the name of this controller.\nconst ControllerName = \"shardlease\"\n\n// AddToManager adds Reconciler to the given manager.\nfunc (r *Reconciler) AddToManager(mgr manager.Manager) error {\n\tif r.Client == nil {\n\t\tr.Client = mgr.GetClient()\n\t}\n\tif r.Clock == nil {\n\t\tr.Clock = clock.RealClock{}\n\t}\n\n\treturn builder.ControllerManagedBy(mgr).\n\t\tNamed(ControllerName).\n\t\tFor(&coordinationv1.Lease{}, builder.WithPredicates(r.LeasePredicate())).\n\t\t// enqueue all Leases belonging to a ControllerRing when it is created or the spec is updated\n\t\tWatches(\n\t\t\t&shardingv1alpha1.ControllerRing{},\n\t\t\thandler.EnqueueRequestsFromMapFunc(shardinghandler.MapControllerRingToLeases(r.Client)),\n\t\t\tbuilder.WithPredicates(shardingpredicate.ControllerRingCreatedOrUpdated()),\n\t\t).\n\t\tWithOptions(controller.Options{\n\t\t\tMaxConcurrentReconciles: 5,\n\t\t\tNewQueue: func(controllerName string, rateLimiter workqueue.TypedRateLimiter[reconcile.Request]) workqueue.TypedRateLimitingInterface[reconcile.Request] {\n\t\t\t\treturn workqueue.NewTypedRateLimitingQueueWithConfig(rateLimiter, workqueue.TypedRateLimitingQueueConfig[reconcile.Request]{\n\t\t\t\t\tName:  controllerName,\n\t\t\t\t\tClock: r.Clock,\n\t\t\t\t})\n\t\t\t},\n\t\t}).\n\t\tComplete(r)\n}\n\nfunc (r *Reconciler) LeasePredicate() predicate.Predicate {\n\treturn predicate.And(\n\t\tshardingpredicate.IsShardLease(),\n\t\tshardingpredicate.ShardLeaseStateChanged(r.Clock),\n\t\t// ignore deletion of shard leases\n\t\tpredicate.Funcs{\n\t\t\tDeleteFunc: func(_ event.DeleteEvent) bool { return false },\n\t\t},\n\t)\n}\n"
  },
  {
    "path": "pkg/controller/shardlease/add_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage shardlease_test\n\nimport (\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/clock/testing\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/controller/shardlease\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n)\n\nvar _ = Describe(\"Reconciler\", func() {\n\tvar r *Reconciler\n\n\tBeforeEach(func() {\n\t\tr = &Reconciler{}\n\t})\n\n\tDescribe(\"#LeasePredicate\", func() {\n\t\tvar (\n\t\t\tp           predicate.Predicate\n\t\t\tobj, objOld *coordinationv1.Lease\n\n\t\t\tfakeClock *testing.FakeClock\n\t\t)\n\n\t\tBeforeEach(func() {\n\t\t\tfakeClock = testing.NewFakeClock(time.Now())\n\t\t\tr.Clock = fakeClock\n\n\t\t\tp = r.LeasePredicate()\n\n\t\t\tobj = &coordinationv1.Lease{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName: \"foo-0\",\n\t\t\t\t},\n\t\t\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\t\t\tHolderIdentity:       ptr.To(\"foo-0\"),\n\t\t\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-5 * time.Minute))),\n\t\t\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-2 * time.Second))),\n\t\t\t\t},\n\t\t\t}\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"alpha.sharding.timebertt.dev/controllerring\", \"foo\")\n\t\t\tobjOld = obj.DeepCopy()\n\t\t})\n\n\t\tIt(\"should ignore leases with empty label\", func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"alpha.sharding.timebertt.dev/controllerring\", \"\")\n\t\t\tobjOld = obj.DeepCopy()\n\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeFalse())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should react on create events for unavailable leases\", func() {\n\t\t\tobj.Spec.HolderIdentity = nil\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should react on create events for available leases\", func() {\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should react when shard state changed to available\", func() {\n\t\t\tobjOld.Spec.HolderIdentity = nil\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should react when shard state changed to unavailable\", func() {\n\t\t\tobj.Spec.HolderIdentity = nil\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should react when shard state changed while still being available\", func() {\n\t\t\tobj.Spec.RenewTime = ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-time.Duration(*obj.Spec.LeaseDurationSeconds+1) * time.Second)))\n\n\t\t\tExpect(leases.ToState(objOld, fakeClock.Now())).To(Equal(leases.Ready))\n\t\t\tExpect(leases.ToState(obj, fakeClock.Now())).To(Equal(leases.Expired))\n\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should ignore when shard state hasn't changed\", func() {\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\n\t\t\tobj.Spec.HolderIdentity = nil\n\t\t\tobjOld.Spec.HolderIdentity = nil\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should ignore delete events\", func() {\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeFalse())\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/controller/shardlease/reconciler.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage shardlease\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/clock\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n)\n\n//+kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,verbs=get;list;watch;update;patch;delete\n\n// Reconciler reconciles shard leases.\ntype Reconciler struct {\n\tClient client.Client\n\tClock  clock.WithTicker\n}\n\n// Reconcile reconciles a Lease object.\nfunc (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {\n\tlog := logf.FromContext(ctx)\n\n\tlease := &coordinationv1.Lease{}\n\tif err := r.Client.Get(ctx, req.NamespacedName, lease); err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\tlog.V(1).Info(\"Object is gone, stop reconciling\")\n\t\t\treturn reconcile.Result{}, nil\n\t\t}\n\t\treturn reconcile.Result{}, fmt.Errorf(\"error retrieving object from store: %w\", err)\n\t}\n\n\tcontrollerRingName := lease.Labels[shardingv1alpha1.LabelControllerRing]\n\tif controllerRingName == \"\" {\n\t\tlog.V(1).Info(\"Ignoring non-shard lease\")\n\t\treturn reconcile.Result{}, nil\n\t}\n\n\tif err := r.Client.Get(ctx, client.ObjectKey{Name: controllerRingName}, &shardingv1alpha1.ControllerRing{}); err != nil {\n\t\tif !apierrors.IsNotFound(err) {\n\t\t\treturn reconcile.Result{}, fmt.Errorf(\"error checking for existence of ControllerRing: %w\", err)\n\t\t}\n\n\t\tlog.V(1).Info(\"Ignoring shard lease without a corresponding ControllerRing\")\n\t\treturn reconcile.Result{}, nil\n\t}\n\n\tvar (\n\t\tnow           = r.Clock.Now()\n\t\tpreviousState = leases.StateFromString(lease.Labels[shardingv1alpha1.LabelState])\n\t\tshard         = leases.ToShard(lease, now)\n\t)\n\tlog = log.WithValues(\"state\", shard.State, \"expirationTime\", shard.Times.Expiration, \"leaseDuration\", shard.Times.LeaseDuration)\n\n\t// maintain state label\n\tif previousState != shard.State {\n\t\tpatch := client.MergeFromWithOptions(lease.DeepCopy(), client.MergeFromWithOptimisticLock{})\n\t\tmetav1.SetMetaDataLabel(&lease.ObjectMeta, shardingv1alpha1.LabelState, shard.State.String())\n\t\tif err := r.Client.Patch(ctx, lease, patch); err != nil {\n\t\t\treturn reconcile.Result{}, fmt.Errorf(\"failed to update state label on lease: %w\", err)\n\t\t}\n\t}\n\n\t// act on state and determine when to check again\n\tvar requeueAfter time.Duration\n\tswitch shard.State {\n\tcase leases.Ready:\n\t\tif previousState != leases.Ready {\n\t\t\tlog.Info(\"Shard got available\")\n\t\t}\n\t\trequeueAfter = shard.Times.ToExpired\n\tcase leases.Expired:\n\t\tlog.Info(\"Shard lease has expired\")\n\t\trequeueAfter = shard.Times.ToUncertain\n\tcase leases.Uncertain:\n\t\tlog.Info(\"Shard lease has expired more than leaseDuration ago, trying to acquire shard lease\")\n\n\t\tnowMicro := metav1.NewMicroTime(now)\n\t\ttransitions := int32(0)\n\t\tif lease.Spec.LeaseTransitions != nil {\n\t\t\ttransitions = *lease.Spec.LeaseTransitions\n\t\t}\n\n\t\tlease.Spec.HolderIdentity = ptr.To(shardingv1alpha1.IdentityShardLeaseController)\n\t\tlease.Spec.LeaseDurationSeconds = ptr.To(2 * int32(shard.Times.LeaseDuration.Round(time.Second).Seconds()))\n\t\tlease.Spec.AcquireTime = &nowMicro\n\t\tlease.Spec.RenewTime = &nowMicro\n\t\tlease.Spec.LeaseTransitions = ptr.To(transitions + 1)\n\t\tif err := r.Client.Update(ctx, lease); err != nil {\n\t\t\treturn reconcile.Result{}, fmt.Errorf(\"error acquiring shard lease: %w\", err)\n\t\t}\n\n\t\t// lease will be enqueued once we observe our previous update via watch\n\t\t// requeue with leaseDuration just to be sure\n\t\trequeueAfter = shard.Times.LeaseDuration\n\tcase leases.Dead:\n\t\tif previousState != leases.Dead {\n\t\t\tlog.Info(\"Shard got unavailable\")\n\t\t}\n\n\t\t// garbage collect later\n\t\trequeueAfter = shard.Times.ToOrphaned\n\tcase leases.Orphaned:\n\t\t// garbage collect and forget orphaned leases\n\t\treturn reconcile.Result{}, r.Client.Delete(ctx, lease)\n\tdefault:\n\t\t// Unknown, forget lease\n\t\treturn reconcile.Result{}, nil\n\t}\n\n\treturn reconcile.Result{RequeueAfter: requeueAfter}, nil\n}\n"
  },
  {
    "path": "pkg/controller/shardlease/shardlease_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage shardlease_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestShardLease(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Shard Lease Controller Suite\")\n}\n"
  },
  {
    "path": "pkg/metrics/add.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage metrics\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/metrics\"\n)\n\nconst Namespace = \"controller_sharding\"\n\n// AddToManager adds all metrics exporters for sharding objects to the manager.\nfunc AddToManager(mgr manager.Manager) error {\n\tif err := ControllerRingExporter.AddToManager(mgr); err != nil {\n\t\treturn fmt.Errorf(\"failed to add ControllerRing exporter: %w\", err)\n\t}\n\n\tif err := ShardExporter.AddToManager(mgr); err != nil {\n\t\treturn fmt.Errorf(\"failed to add shard exporter: %w\", err)\n\t}\n\n\tfor _, collector := range []prometheus.Collector{\n\t\tAssignmentsTotal,\n\t\tMovementsTotal,\n\t\tDrainsTotal,\n\t\tRingCalculationsTotal,\n\t} {\n\t\tif err := metrics.Registry.Register(collector); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to add sharding operations metrics: %w\", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/metrics/controllerring.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage metrics\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/metrics/exporter\"\n)\n\nvar ControllerRingExporter = exporter.Exporter[*shardingv1alpha1.ControllerRing, *shardingv1alpha1.ControllerRingList]{\n\tNamespace: Namespace,\n\tSubsystem: \"controllerring\",\n\n\tStaticLabelKeys: []string{\"controllerring\", \"uid\"},\n\tGenerateStaticLabelValues: func(controllerRing *shardingv1alpha1.ControllerRing) []string {\n\t\treturn []string{controllerRing.Name, string(controllerRing.UID)}\n\t},\n\n\tMetrics: []exporter.Metric[*shardingv1alpha1.ControllerRing]{\n\t\t{\n\t\t\tName: \"metadata_generation\",\n\t\t\tHelp: \"The generation of a ControllerRing\",\n\n\t\t\tGenerate: func(desc *prometheus.Desc, controllerRing *shardingv1alpha1.ControllerRing, staticLabelValues []string, ch chan<- prometheus.Metric) {\n\t\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\t\tdesc,\n\t\t\t\t\tprometheus.GaugeValue,\n\t\t\t\t\tfloat64(controllerRing.Generation),\n\t\t\t\t\tstaticLabelValues...,\n\t\t\t\t)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName: \"observed_generation\",\n\t\t\tHelp: \"The latest generation observed by the ControllerRing controller\",\n\n\t\t\tGenerate: func(desc *prometheus.Desc, controllerRing *shardingv1alpha1.ControllerRing, staticLabelValues []string, ch chan<- prometheus.Metric) {\n\t\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\t\tdesc,\n\t\t\t\t\tprometheus.GaugeValue,\n\t\t\t\t\tfloat64(controllerRing.Status.ObservedGeneration),\n\t\t\t\t\tstaticLabelValues...,\n\t\t\t\t)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName: \"status_shards\",\n\t\t\tHelp: \"The ControllerRing's total number of shards observed by the ControllerRing controller\",\n\n\t\t\tGenerate: func(desc *prometheus.Desc, controllerRing *shardingv1alpha1.ControllerRing, staticLabelValues []string, ch chan<- prometheus.Metric) {\n\t\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\t\tdesc,\n\t\t\t\t\tprometheus.GaugeValue,\n\t\t\t\t\tfloat64(controllerRing.Status.Shards),\n\t\t\t\t\tstaticLabelValues...,\n\t\t\t\t)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName: \"status_available_shards\",\n\t\t\tHelp: \"The ControllerRing's number of available shards observed by the ControllerRing controller\",\n\n\t\t\tGenerate: func(desc *prometheus.Desc, controllerRing *shardingv1alpha1.ControllerRing, staticLabelValues []string, ch chan<- prometheus.Metric) {\n\t\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\t\tdesc,\n\t\t\t\t\tprometheus.GaugeValue,\n\t\t\t\t\tfloat64(controllerRing.Status.AvailableShards),\n\t\t\t\t\tstaticLabelValues...,\n\t\t\t\t)\n\t\t\t},\n\t\t},\n\t},\n}\n"
  },
  {
    "path": "pkg/metrics/exporter/exporter.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage exporter\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"time\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"k8s.io/apimachinery/pkg/api/meta\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/metrics\"\n)\n\n// Exporter is a generic state metrics exporter for a given Kubernetes object kind that can be added to a\n// controller-runtime manager.\ntype Exporter[O client.Object, L client.ObjectList] struct {\n\tclient.Reader\n\n\tNamespace, Subsystem string\n\n\t// StaticLabelKeys are added to all Metrics of this Exporter.\n\tStaticLabelKeys []string\n\t// GenerateStaticLabelValues returns the values for StaticLabelKeys.\n\tGenerateStaticLabelValues func(O) []string\n\n\tMetrics []Metric[O]\n\n\t// optional\n\tListOptions []client.ListOption\n}\n\n// Metric describes a single metric and how to generate it per object.\ntype Metric[O client.Object] struct {\n\tName, Help string\n\tLabelKeys  []string\n\n\t// Generate returns all metric values for the given object.\n\t// staticLabelValues is the result of Exporter.GenerateStaticLabelValues and should be added as the first label values\n\t// to all metrics.\n\tGenerate GenerateFunc[O]\n\n\t// desc is completed in Exporter.AddToManager.\n\tdesc *prometheus.Desc\n}\n\ntype GenerateFunc[O client.Object] func(desc *prometheus.Desc, obj O, staticLabelValues []string, ch chan<- prometheus.Metric)\n\n// AddToManager adds this exporter to the given manager and completes the Metrics descriptors.\nfunc (e *Exporter[O, L]) AddToManager(mgr manager.Manager) error {\n\tif e.Reader == nil {\n\t\te.Reader = mgr.GetCache()\n\t}\n\n\tfor i, m := range e.Metrics {\n\t\tm.desc = prometheus.NewDesc(\n\t\t\tprometheus.BuildFQName(e.Namespace, e.Subsystem, m.Name),\n\t\t\tm.Help,\n\t\t\tappend(e.StaticLabelKeys, m.LabelKeys...),\n\t\t\tnil,\n\t\t)\n\t\te.Metrics[i] = m\n\t}\n\n\treturn mgr.Add(e)\n}\n\n// NeedLeaderElection tells the manager to run the exporter in all instances.\nfunc (e *Exporter[O, L]) NeedLeaderElection() bool {\n\treturn false\n}\n\n// Start registers this collector in the controller-runtime metrics registry.\n// When Start runs, caches have already been started, so we are ready to export metrics.\nfunc (e *Exporter[O, L]) Start(_ context.Context) error {\n\tif err := metrics.Registry.Register(e); err != nil {\n\t\treturn fmt.Errorf(\"failed to register %s exporter: %w\", e.Subsystem, err)\n\t}\n\n\treturn nil\n}\n\nfunc (e *Exporter[O, L]) Describe(ch chan<- *prometheus.Desc) {\n\tfor _, m := range e.Metrics {\n\t\tch <- m.desc\n\t}\n}\n\nfunc (e *Exporter[O, L]) Collect(ch chan<- prometheus.Metric) {\n\tctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)\n\tdefer cancel()\n\n\tlist := reflect.New(reflect.TypeOf(*new(L)).Elem()).Interface().(client.ObjectList)\n\tif err := e.List(ctx, list, e.ListOptions...); err != nil {\n\t\te.handleError(ch, fmt.Errorf(\"error listing %T: %w\", list, err))\n\t\treturn\n\t}\n\n\tif err := meta.EachListItem(list, func(obj runtime.Object) error {\n\t\to := obj.(O)\n\t\tstaticLabelValues := e.GenerateStaticLabelValues(o)\n\n\t\tfor _, m := range e.Metrics {\n\t\t\tm.Generate(m.desc, o, staticLabelValues, ch)\n\t\t}\n\n\t\treturn nil\n\t}); err != nil {\n\t\te.handleError(ch, fmt.Errorf(\"error iterarting %T: %w\", list, err))\n\t\treturn\n\t}\n}\n\nfunc (e *Exporter[O, L]) handleError(ch chan<- prometheus.Metric, err error) {\n\tfor _, m := range e.Metrics {\n\t\tch <- prometheus.NewInvalidMetric(m.desc, err)\n\t}\n}\n\n// GenerateStateSet returns a GenerateFunc that emits stateset metrics:\n// - it generates one metric per known state\n// - the value is 1 if getState returns the state, 0 otherwise\n// - if unknownState is given, a metric with this state label is generated with value 1 if no other state has matched\nfunc GenerateStateSet[O client.Object](knownStates []string, unknownState *string, getState func(O) string) GenerateFunc[O] {\n\treturn func(desc *prometheus.Desc, obj O, staticLabelValues []string, ch chan<- prometheus.Metric) {\n\t\tactual := getState(obj)\n\n\t\t// generate metrics for all known states\n\t\tknown := false\n\t\tfor _, state := range knownStates {\n\t\t\thasState := actual == state\n\t\t\tif hasState {\n\t\t\t\tknown = true\n\t\t\t}\n\n\t\t\tch <- stateSetMetric(desc, state, hasState, staticLabelValues)\n\t\t}\n\n\t\tif unknownState != nil {\n\t\t\t// generate a metric for unknown states\n\t\t\tch <- stateSetMetric(desc, *unknownState, !known, staticLabelValues)\n\t\t}\n\t}\n}\n\nfunc stateSetMetric(desc *prometheus.Desc, state string, value bool, staticLabelValues []string) prometheus.Metric {\n\tv := 0\n\tif value {\n\t\tv = 1\n\t}\n\n\treturn prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, float64(v), append(staticLabelValues, state)...)\n}\n\n// KnownStates converts the given slice of ~string to a slice of strings.\nfunc KnownStates[T ~string](s []T) []string {\n\tout := make([]string, len(s))\n\tfor i := range s {\n\t\tout[i] = string(s[i])\n\t}\n\treturn out\n}\n\n// KnownStatesStringer converts the given slice of fmt.Stringer to a slice of strings.\nfunc KnownStatesStringer[T fmt.Stringer](s []T) []string {\n\tout := make([]string, len(s))\n\tfor i := range s {\n\t\tout[i] = s[i].String()\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "pkg/metrics/operations.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage metrics\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\nvar (\n\t// AssignmentsTotal is a prometheus counter metric which holds the total number of shard assignments by the sharder\n\t// webhook per ControllerRing and GroupResource.\n\t// It has a label which refers to the ControllerRing and two labels which refer to the object's GroupResource.\n\tAssignmentsTotal = prometheus.NewCounterVec(prometheus.CounterOpts{\n\t\tNamespace: Namespace,\n\t\tName:      \"assignments_total\",\n\t\tHelp:      \"Total number of shard assignments by the sharder webhook per ControllerRing and GroupResource\",\n\t}, []string{\"controllerring\", \"group\", \"resource\"})\n\n\t// MovementsTotal is a prometheus counter metric which holds the total number of shard movements triggered by the\n\t// sharder controller per ControllerRing and GroupResource.\n\t// It has a label which refers to the ControllerRing and two labels which refer to the object's GroupResource.\n\tMovementsTotal = prometheus.NewCounterVec(prometheus.CounterOpts{\n\t\tNamespace: Namespace,\n\t\tName:      \"movements_total\",\n\t\tHelp:      \"Total number of shard movements triggered by the sharder controller per ControllerRing and GroupResource\",\n\t}, []string{\"controllerring\", \"group\", \"resource\"})\n\n\t// DrainsTotal is a prometheus counter metric which holds the total number of shard drains triggered by the sharder\n\t// controller per ControllerRing and GroupResource.\n\t// It has a label which refers to the ControllerRing and two labels which refer to the object's GroupResource.\n\tDrainsTotal = prometheus.NewCounterVec(prometheus.CounterOpts{\n\t\tNamespace: Namespace,\n\t\tName:      \"drains_total\",\n\t\tHelp:      \"Total number of shard drains triggered by the sharder controller per ControllerRing and GroupResource\",\n\t}, []string{\"controllerring\", \"group\", \"resource\"})\n\n\t// RingCalculationsTotal is a prometheus counter metric which holds the total\n\t// number of hash ring calculations per ControllerRing.\n\t// It has a label which refers to the ControllerRing.\n\tRingCalculationsTotal = prometheus.NewCounterVec(prometheus.CounterOpts{\n\t\tNamespace: Namespace,\n\t\tName:      \"ring_calculations_total\",\n\t\tHelp:      \"Total number of hash ring calculations per ControllerRing\",\n\t}, []string{\"controllerring\"})\n)\n"
  },
  {
    "path": "pkg/metrics/shard.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage metrics\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/metrics/exporter\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n)\n\nvar ShardExporter = exporter.Exporter[*coordinationv1.Lease, *coordinationv1.LeaseList]{\n\tNamespace: Namespace,\n\tSubsystem: \"shard\",\n\n\tListOptions: []client.ListOption{client.HasLabels{shardingv1alpha1.LabelControllerRing}},\n\n\tStaticLabelKeys: []string{\"namespace\", \"shard\", \"controllerring\"},\n\tGenerateStaticLabelValues: func(lease *coordinationv1.Lease) []string {\n\t\treturn []string{lease.Namespace, lease.Name, lease.Labels[shardingv1alpha1.LabelControllerRing]}\n\t},\n\n\tMetrics: []exporter.Metric[*coordinationv1.Lease]{\n\t\t{\n\t\t\tName:      \"info\",\n\t\t\tHelp:      \"Information about a shard\",\n\t\t\tLabelKeys: []string{\"uid\"},\n\n\t\t\tGenerate: func(desc *prometheus.Desc, lease *coordinationv1.Lease, staticLabelValues []string, ch chan<- prometheus.Metric) {\n\t\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\t\tdesc,\n\t\t\t\t\tprometheus.GaugeValue,\n\t\t\t\t\t1,\n\t\t\t\t\tappend(staticLabelValues, string(lease.UID))...,\n\t\t\t\t)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName:      \"state\",\n\t\t\tHelp:      \"The shard's current state observed by the shardlease controller\",\n\t\t\tLabelKeys: []string{\"state\"},\n\n\t\t\tGenerate: exporter.GenerateStateSet[*coordinationv1.Lease](\n\t\t\t\texporter.KnownStatesStringer(leases.KnownShardStates), ptr.To(leases.Unknown.String()),\n\t\t\t\tfunc(lease *coordinationv1.Lease) string {\n\t\t\t\t\treturn lease.Labels[shardingv1alpha1.LabelState]\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t},\n}\n"
  },
  {
    "path": "pkg/shard/controller/builder.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller\n\nimport (\n\t\"fmt\"\n\n\tutilruntime \"k8s.io/apimachinery/pkg/util/runtime\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n)\n\n// Builder can build a sharded reconciler.\n// Use NewShardedReconciler to create a new Builder.\ntype Builder struct {\n\tobject             client.Object\n\tclient             client.Client\n\tcontrollerRingName string\n\tshardName          string\n\terr                error\n}\n\n// NewShardedReconciler returns a new Builder for building a sharded reconciler.\n// A sharded reconciler needs to handle the shard and drain labels correctly. This builder helps to construct a wrapper\n// reconciler that takes care of the sharding-related logic and calls the delegate reconciler whenever the shard is\n// responsible for reconciling an object.\nfunc NewShardedReconciler(mgr manager.Manager) *Builder {\n\treturn (&Builder{}).WithClient(mgr.GetClient())\n}\n\n// For sets the object kind being reconciled by the reconciler.\nfunc (b *Builder) For(object client.Object) *Builder {\n\tif b.object != nil {\n\t\tb.err = fmt.Errorf(\"must not call For() more than once\")\n\t\treturn b\n\t}\n\tb.object = object\n\treturn b\n}\n\n// WithClient overwrites the client to use for reading and patching the controller's objects.\n// If not set, the manager's client is used.\nfunc (b *Builder) WithClient(c client.Client) *Builder {\n\tb.client = c\n\treturn b\n}\n\n// InControllerRing sets the name of the ControllerRing that the shard belongs to.\nfunc (b *Builder) InControllerRing(name string) *Builder {\n\tb.controllerRingName = name\n\treturn b\n}\n\n// WithShardName sets the name the shard.\nfunc (b *Builder) WithShardName(name string) *Builder {\n\tb.shardName = name\n\treturn b\n}\n\n// MustBuild calls Build and panics if Build returns an error.\nfunc (b *Builder) MustBuild(r reconcile.Reconciler) reconcile.Reconciler {\n\tresult, err := b.Build(r)\n\tutilruntime.Must(err)\n\treturn result\n}\n\n// Build takes the actual reconciler and wraps it in the sharded reconciler.\nfunc (b *Builder) Build(r reconcile.Reconciler) (reconcile.Reconciler, error) {\n\tif b.err != nil {\n\t\treturn nil, b.err\n\t}\n\tif r == nil {\n\t\treturn nil, fmt.Errorf(\"must provide a non-nil Reconciler\")\n\t}\n\tif b.object == nil {\n\t\treturn nil, fmt.Errorf(\"missing object kind, must call to For()\")\n\t}\n\tif b.client == nil {\n\t\treturn nil, fmt.Errorf(\"missing client\")\n\t}\n\tif b.controllerRingName == \"\" {\n\t\treturn nil, fmt.Errorf(\"missing ControllerRing name\")\n\t}\n\tif b.shardName == \"\" {\n\t\treturn nil, fmt.Errorf(\"missing shard name\")\n\t}\n\n\treturn &Reconciler{\n\t\tObject:             b.object,\n\t\tClient:             b.client,\n\t\tControllerRingName: b.controllerRingName,\n\t\tShardName:          b.shardName,\n\t\tDo:                 r,\n\t}, nil\n}\n"
  },
  {
    "path": "pkg/shard/controller/builder_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller_test\n\nimport (\n\t\"context\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\tfakeclient \"sigs.k8s.io/controller-runtime/pkg/client/fake\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/shard/controller\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nvar _ = Describe(\"#Builder\", func() {\n\tvar (\n\t\tmgr fakeManager\n\t\tb   *Builder\n\n\t\tobj                *corev1.Pod\n\t\tcontrollerRingName string\n\t\tshardName          string\n\t\tclient             client.Client\n\t\tr                  reconcile.Reconciler\n\t)\n\n\tBeforeEach(func() {\n\t\tobj = &corev1.Pod{}\n\t\tcontrollerRingName = \"operator\"\n\t\tshardName = \"operator-0\"\n\t\tclient = fakeclient.NewFakeClient()\n\t\tr = reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) {\n\t\t\treturn reconcile.Result{}, nil\n\t\t})\n\t})\n\n\tJustBeforeEach(func() {\n\t\tmgr = fakeManager{Client: client}\n\t\tb = NewShardedReconciler(mgr).\n\t\t\tFor(obj).\n\t\t\tInControllerRing(controllerRingName).\n\t\t\tWithShardName(shardName)\n\t})\n\n\tDescribe(\"#For\", func() {\n\t\tIt(\"should complain about calling For twice\", func() {\n\t\t\tExpect(b.For(obj).Build(r)).Error().To(MatchError(\"must not call For() more than once\"))\n\t\t})\n\n\t\tIt(\"should complain about not calling For\", func() {\n\t\t\tb = NewShardedReconciler(mgr).\n\t\t\t\tInControllerRing(controllerRingName).\n\t\t\t\tWithShardName(shardName)\n\t\t\tExpect(b.Build(r)).Error().To(MatchError(\"missing object kind, must call to For()\"))\n\t\t})\n\t})\n\n\tDescribe(\"#WithClient\", func() {\n\t\tIt(\"should use the custom client instead of the manager's client\", func() {\n\t\t\tcustomClient := fakeclient.NewFakeClient()\n\t\t\tExpect(b.WithClient(customClient).Build(r)).To(\n\t\t\t\tHaveField(\"Client\", BeIdenticalTo(customClient)),\n\t\t\t)\n\t\t})\n\n\t\tIt(\"should complain about missing client\", func() {\n\t\t\tExpect(b.WithClient(nil).Build(r)).Error().To(MatchError(\"missing client\"))\n\t\t})\n\t})\n\n\tDescribe(\"#InControllerRing\", func() {\n\t\tIt(\"should complain about missing ControllerRing name\", func() {\n\t\t\tExpect(b.InControllerRing(\"\").Build(r)).Error().To(MatchError(\"missing ControllerRing name\"))\n\t\t})\n\t})\n\n\tDescribe(\"#WithShardName\", func() {\n\t\tIt(\"should complain about missing shard name\", func() {\n\t\t\tExpect(b.WithShardName(\"\").Build(r)).Error().To(MatchError(\"missing shard name\"))\n\t\t})\n\t})\n\n\tDescribe(\"#Build\", func() {\n\t\tIt(\"should complain about nil reconciler\", func() {\n\t\t\tExpect(b.Build(nil)).Error().To(MatchError(\"must provide a non-nil Reconciler\"))\n\t\t})\n\n\t\tIt(\"should correctly set up the Reconciler\", func() {\n\t\t\tshardReconciler, err := b.Build(r)\n\t\t\tExpect(err).NotTo(HaveOccurred())\n\n\t\t\treconciler, ok := shardReconciler.(*Reconciler)\n\t\t\tExpect(ok).To(BeTrue())\n\n\t\t\tExpect(reconciler.Object).To(BeAssignableToTypeOf(obj))\n\t\t\tExpect(reconciler.Client).To(BeIdenticalTo(client))\n\t\t\tExpect(reconciler.ControllerRingName).To(Equal(controllerRingName))\n\t\t\tExpect(reconciler.ShardName).To(Equal(shardName))\n\t\t\tExpect(reconciler.Do).To(BeFunc(r))\n\t\t})\n\t})\n\n\tDescribe(\"#MustBuild\", func() {\n\t\tIt(\"should panic for nil reconciler\", func() {\n\t\t\tExpect(func() {\n\t\t\t\tb.MustBuild(nil)\n\t\t\t}).To(Panic())\n\t\t})\n\n\t\tIt(\"should correctly set up the Reconciler\", func() {\n\t\t\tvar shardReconciler reconcile.Reconciler\n\t\t\tExpect(func() {\n\t\t\t\tshardReconciler = b.MustBuild(r)\n\t\t\t}).NotTo(Panic())\n\n\t\t\treconciler, ok := shardReconciler.(*Reconciler)\n\t\t\tExpect(ok).To(BeTrue())\n\n\t\t\tExpect(reconciler.Object).To(BeAssignableToTypeOf(obj))\n\t\t\tExpect(reconciler.Client).To(BeIdenticalTo(client))\n\t\t\tExpect(reconciler.ControllerRingName).To(Equal(controllerRingName))\n\t\t\tExpect(reconciler.ShardName).To(Equal(shardName))\n\t\t\tExpect(reconciler.Do).To(BeFunc(r))\n\t\t})\n\t})\n})\n\ntype fakeManager struct {\n\tmanager.Manager\n\tClient client.Client\n}\n\nfunc (f fakeManager) GetClient() client.Client {\n\treturn f.Client\n}\n"
  },
  {
    "path": "pkg/shard/controller/controller_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestController(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Shard Controller Suite\")\n}\n"
  },
  {
    "path": "pkg/shard/controller/predicate.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller\n\nimport (\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n)\n\n// Predicate sets up a predicate that evaluates to true if\n// a) the object needs to be drained or\n// b) the given shard is responsible and all other predicates match.\n// To support sharding in your controller, use this function to construct a predicate for the object kind given to\n// `builder.Builder.For` (i.e., the controller's main kind).\n// It is not needed to use this predicate for secondary watches (e.g., for object kinds given to\n// `builder.Builder.{Owns,Watches}`) as secondary objects are not drained by the sharder.\nfunc Predicate(controllerRingName, shardName string, predicates ...predicate.Predicate) predicate.Predicate {\n\treturn predicate.Or(\n\t\t// always enqueue if we need to acknowledge the drain operation, other predicates don't matter in this case\n\t\tisDrained(controllerRingName),\n\t\t// or enqueue if we are responsible and all other predicates match\n\t\tpredicate.And(isAssigned(controllerRingName, shardName), predicate.And(predicates...)),\n\t)\n}\n\nfunc isAssigned(controllerRingName, shardName string) predicate.Predicate {\n\treturn predicate.NewPredicateFuncs(func(object client.Object) bool {\n\t\treturn object.GetLabels()[shardingv1alpha1.LabelShard(controllerRingName)] == shardName\n\t})\n}\n\nfunc isDrained(controllerRingName string) predicate.Predicate {\n\treturn predicate.NewPredicateFuncs(func(object client.Object) bool {\n\t\t_, drain := object.GetLabels()[shardingv1alpha1.LabelDrain(controllerRingName)]\n\t\treturn drain\n\t})\n}\n"
  },
  {
    "path": "pkg/shard/controller/predicate_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller_test\n\nimport (\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/shard/controller\"\n)\n\nvar _ = Describe(\"#Predicate\", func() {\n\tvar (\n\t\tcontrollerRingName string\n\t\tshardName          string\n\n\t\tmainPredicate, p predicate.Predicate\n\n\t\tobj, objOld *corev1.Pod\n\t)\n\n\tBeforeEach(func() {\n\t\tcontrollerRingName = \"operator\"\n\t\tshardName = \"operator-0\"\n\n\t\tobj = &corev1.Pod{}\n\t})\n\n\tJustBeforeEach(func() {\n\t\tp = Predicate(controllerRingName, shardName, mainPredicate)\n\t})\n\n\tWhen(\"main predicate returns false\", func() {\n\t\tBeforeEach(func() {\n\t\t\tmainPredicate = predicate.NewPredicateFuncs(func(client.Object) bool {\n\t\t\t\treturn false\n\t\t\t})\n\t\t})\n\n\t\tIt(\"should handle drained objects\", func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"drain.alpha.sharding.timebertt.dev/\"+controllerRingName, \"true\")\n\t\t\tobjOld = obj.DeepCopy()\n\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeTrue())\n\t\t\tExpect(p.Generic(event.GenericEvent{Object: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should handle assigned and drained objects\", func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"shard.alpha.sharding.timebertt.dev/\"+controllerRingName, shardName)\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"drain.alpha.sharding.timebertt.dev/\"+controllerRingName, \"true\")\n\t\t\tobjOld = obj.DeepCopy()\n\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeTrue())\n\t\t\tExpect(p.Generic(event.GenericEvent{Object: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should not handle assigned objects\", func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"shard.alpha.sharding.timebertt.dev/\"+controllerRingName, shardName)\n\t\t\tobjOld = obj.DeepCopy()\n\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeFalse())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeFalse())\n\t\t\tExpect(p.Generic(event.GenericEvent{Object: obj})).To(BeFalse())\n\t\t})\n\t})\n\n\tWhen(\"main predicate returns true\", func() {\n\t\tBeforeEach(func() {\n\t\t\tmainPredicate = predicate.NewPredicateFuncs(func(client.Object) bool {\n\t\t\t\treturn true\n\t\t\t})\n\t\t})\n\n\t\tIt(\"should handle drained objects\", func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"drain.alpha.sharding.timebertt.dev/\"+controllerRingName, \"true\")\n\t\t\tobjOld = obj.DeepCopy()\n\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeTrue())\n\t\t\tExpect(p.Generic(event.GenericEvent{Object: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should handle assigned objects\", func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"shard.alpha.sharding.timebertt.dev/\"+controllerRingName, shardName)\n\t\t\tobjOld = obj.DeepCopy()\n\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeTrue())\n\t\t\tExpect(p.Generic(event.GenericEvent{Object: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should handle assigned and drained objects\", func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"shard.alpha.sharding.timebertt.dev/\"+controllerRingName, shardName)\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"drain.alpha.sharding.timebertt.dev/\"+controllerRingName, \"true\")\n\t\t\tobjOld = obj.DeepCopy()\n\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeTrue())\n\t\t\tExpect(p.Generic(event.GenericEvent{Object: obj})).To(BeTrue())\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/shard/controller/reconciler.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n)\n\n// Reconciler wraps another reconciler to ensure that the controller correctly handles the shard and drain labels.\n// It ignores any objects that are not assigned to the configured shard name and drains objects if instructed to by\n// the sharder.\n// You can use NewShardedReconciler to construct a sharded reconciler.\ntype Reconciler struct {\n\t// Object is the object type of the controller.\n\tObject client.Object\n\t// Client is used to read and patch the controller's objects.\n\tClient client.Client\n\t// ControllerRingName is the name of the manager's ControllerRing.\n\tControllerRingName string\n\t// ShardName is the shard ID of the manager.\n\tShardName string\n\t// Do is the actual Reconciler.\n\tDo reconcile.Reconciler\n}\n\n// Reconcile implements reconcile.Reconciler. It performs the following steps:\n// 1) read the object using the client, forget the object if it is not found\n// 2) check whether the object is (still) assigned to this shard, forget the object otherwise\n// 3) acknowledge the drain operation if requested by removing the shard and drain label, skip reconciliation, and forget the object\n// 4) delegate reconciliation to the actual reconciler otherwise\nfunc (r *Reconciler) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {\n\tlog := logf.FromContext(ctx)\n\n\tobj := r.Object.DeepCopyObject().(client.Object)\n\tif err := r.Client.Get(ctx, request.NamespacedName, obj); err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\tlog.V(1).Info(\"Object is gone or not assigned to this shard anymore, stop reconciling\")\n\t\t\treturn reconcile.Result{}, nil\n\t\t}\n\t\treturn reconcile.Result{}, fmt.Errorf(\"error retrieving object from store for determining responsibility: %w\", err)\n\t}\n\n\tvar (\n\t\tlabels     = obj.GetLabels()\n\t\tlabelShard = shardingv1alpha1.LabelShard(r.ControllerRingName)\n\t\tlabelDrain = shardingv1alpha1.LabelDrain(r.ControllerRingName)\n\t)\n\n\t// check if we are responsible for this object\n\t// Note that objects should already be filtered by the cache and the predicate for being assigned to this shard.\n\t// However, we still need to do a final check before reconciling here. The controller might requeue the object with\n\t// a delay or exponential. This might trigger another reconciliation even after observing a label change.\n\tif shard, ok := labels[labelShard]; !ok || shard != r.ShardName {\n\t\tlog.V(1).Info(\"Ignoring object as it is not assigned to this shard\", \"shard\", shard)\n\t\treturn reconcile.Result{}, nil\n\t}\n\n\tif _, drain := labels[labelDrain]; drain {\n\t\tlog.V(1).Info(\"Draining object\")\n\n\t\t// acknowledge drain operation\n\t\tpatch := client.MergeFromWithOptions(obj.DeepCopyObject().(client.Object), client.MergeFromWithOptimisticLock{})\n\t\tdelete(labels, labelShard)\n\t\tdelete(labels, labelDrain)\n\n\t\tif err := r.Client.Patch(ctx, obj, patch); err != nil {\n\t\t\treturn reconcile.Result{}, fmt.Errorf(\"error draining object: %w\", err)\n\t\t}\n\n\t\t// forget object\n\t\treturn reconcile.Result{}, nil\n\t}\n\n\t// we are responsible, reconcile object\n\treturn r.Do.Reconcile(ctx, request)\n}\n"
  },
  {
    "path": "pkg/shard/controller/reconciler_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\t. \"github.com/onsi/gomega/gbytes\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\tfakeclient \"sigs.k8s.io/controller-runtime/pkg/client/fake\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/shard/controller\"\n)\n\nvar _ = Describe(\"#Reconciler\", func() {\n\tvar (\n\t\tctx context.Context\n\n\t\tlogBuffer *Buffer\n\n\t\tcontrollerRingName string\n\t\tshardName          string\n\n\t\tfakeClient client.Client\n\n\t\tr *Reconciler\n\n\t\tobj *corev1.Pod\n\t\treq reconcile.Request\n\t)\n\n\tBeforeEach(func() {\n\t\tlogBuffer = NewBuffer()\n\t\tctx = logf.IntoContext(context.Background(), zap.New(zap.UseDevMode(true), zap.WriteTo(io.MultiWriter(logBuffer, GinkgoWriter))))\n\n\t\tcontrollerRingName = \"operator\"\n\t\tshardName = \"operator-0\"\n\n\t\tfakeClient = fakeclient.NewFakeClient()\n\n\t\tr = &Reconciler{\n\t\t\tObject:             &corev1.Pod{},\n\t\t\tClient:             fakeClient,\n\t\t\tControllerRingName: controllerRingName,\n\t\t\tShardName:          shardName,\n\t\t}\n\n\t\tobj = &corev1.Pod{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tName:      \"foo\",\n\t\t\t\tNamespace: \"bar\",\n\t\t\t},\n\t\t}\n\t\treq = reconcile.Request{NamespacedName: client.ObjectKeyFromObject(obj)}\n\t})\n\n\tJustBeforeEach(func() {\n\t\tif obj != nil {\n\t\t\tExpect(fakeClient.Create(ctx, obj)).To(Succeed())\n\t\t}\n\t})\n\n\tWhen(\"the object does not exist\", func() {\n\t\tBeforeEach(func() {\n\t\t\tobj = nil\n\t\t})\n\n\t\tIt(\"should ignore the request\", func() {\n\t\t\tExpect(r.Reconcile(ctx, req)).To(BeZero())\n\t\t\tEventually(logBuffer).Should(Say(\"Object is gone\"))\n\t\t})\n\t})\n\n\tWhen(\"the object is assigned to another shard\", func() {\n\t\tBeforeEach(func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"shard.alpha.sharding.timebertt.dev/\"+controllerRingName, \"other\")\n\t\t})\n\n\t\tIt(\"should ignore the request\", func() {\n\t\t\tExpect(r.Reconcile(ctx, req)).To(BeZero())\n\t\t\tEventually(logBuffer).Should(Say(\"Ignoring object as it is not assigned to this shard\"))\n\t\t})\n\t})\n\n\tWhen(\"the object is assigned to this shard\", func() {\n\t\tBeforeEach(func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"shard.alpha.sharding.timebertt.dev/\"+controllerRingName, shardName)\n\t\t})\n\n\t\tWhen(\"the object is drained\", func() {\n\t\t\tBeforeEach(func() {\n\t\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"drain.alpha.sharding.timebertt.dev/\"+controllerRingName, \"true\")\n\t\t\t})\n\n\t\t\tIt(\"should remove the shard and drain label\", func() {\n\t\t\t\tExpect(r.Reconcile(ctx, req)).To(BeZero())\n\t\t\t\tEventually(logBuffer).Should(Say(\"Draining object\"))\n\n\t\t\t\tExpect(fakeClient.Get(ctx, client.ObjectKeyFromObject(obj), obj)).To(Succeed())\n\t\t\t\tExpect(obj.GetLabels()).Should(BeEmpty())\n\t\t\t})\n\t\t})\n\n\t\tWhen(\"the object is not drained\", func() {\n\t\t\tvar (\n\t\t\t\tresult reconcile.Result\n\t\t\t\terr    error\n\t\t\t\tcalled int\n\t\t\t)\n\n\t\t\tBeforeEach(func() {\n\t\t\t\tresult, err = reconcile.Result{}, nil\n\t\t\t\tcalled = 0\n\n\t\t\t\tr.Do = reconcile.Func(func(context.Context, reconcile.Request) (reconcile.Result, error) {\n\t\t\t\t\tcalled++\n\t\t\t\t\treturn result, err\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tIt(\"should call the reconciler and return its result\", func() {\n\t\t\t\tExpect(r.Reconcile(ctx, req)).To(BeZero())\n\t\t\t\tExpect(called).To(Equal(1))\n\n\t\t\t\tresult = reconcile.Result{Requeue: true}\n\t\t\t\tExpect(r.Reconcile(ctx, req)).To(Equal(reconcile.Result{Requeue: true}))\n\t\t\t\tExpect(called).To(Equal(2))\n\n\t\t\t\tresult = reconcile.Result{}\n\t\t\t\terr = fmt.Errorf(\"foo\")\n\t\t\t\tExpect(r.Reconcile(ctx, req)).Error().To(MatchError(\"foo\"))\n\t\t\t\tExpect(called).To(Equal(3))\n\t\t\t})\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/shard/lease/lease.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage lease\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"os\"\n\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\tcoordinationv1client \"k8s.io/client-go/kubernetes/typed/coordination/v1\"\n\t\"k8s.io/client-go/rest\"\n\t\"k8s.io/client-go/tools/leaderelection/resourcelock\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n)\n\n// Options provides the required configuration to create a new shard lease.\ntype Options struct {\n\t// ControllerRingName specifies the name of the ControllerRing that the shard belongs to.\n\tControllerRingName string\n\t// LeaseNamespace determines the namespace in which the shard lease will be created.\n\t// Defaults to the pod's namespace if running in-cluster.\n\tLeaseNamespace string\n\t// ShardName determines the name of the shard. This will be used as the lease name as well as the lease's\n\t// holderIdentity.\n\t// Defaults to os.Hostname().\n\tShardName string\n}\n\n// NewResourceLock returns a new resource lock that implements the shard lease.\n// Pass this to the leader elector, e.g., leaderelection.LeaderElectionConfig.Lock (if using plain client-go) or\n// manager.Options.LeaderElectionResourceLockInterface (if using controller-runtime).\nfunc NewResourceLock(config *rest.Config, options Options) (resourcelock.Interface, error) {\n\t// Construct client for leader election\n\trest.AddUserAgent(config, \"shard-lease\")\n\n\t// We use plain client-go here instead of controller-runtime to avoid pulling in the controller-runtime dependency\n\t// for projects that want to use this helper but don't use controller-runtime.\n\tcoordinationClient, err := coordinationv1client.NewForConfig(config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif options.ControllerRingName == \"\" {\n\t\treturn nil, errors.New(\"ControllerRingName is required\")\n\t}\n\n\t// default shard name to hostname if not set\n\tif options.ShardName == \"\" {\n\t\toptions.ShardName, err = os.Hostname()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error getting hostname: %w\", err)\n\t\t}\n\t}\n\n\t// default namespace to pod's namespace if running in-cluster\n\tif options.LeaseNamespace == \"\" {\n\t\toptions.LeaseNamespace, err = getInClusterNamespace()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to determine shard lease namespace: %w\", err)\n\t\t}\n\t}\n\n\treturn &LeaseLock{\n\t\tLeaseMeta: metav1.ObjectMeta{\n\t\t\tNamespace: options.LeaseNamespace,\n\t\t\tName:      options.ShardName,\n\t\t},\n\t\tClient: coordinationClient,\n\t\tLockConfig: resourcelock.ResourceLockConfig{\n\t\t\tIdentity: options.ShardName,\n\t\t},\n\t\tLabels: map[string]string{\n\t\t\tshardingv1alpha1.LabelControllerRing: options.ControllerRingName,\n\t\t},\n\t}, nil\n}\n\n// LeaseLock implements resourcelock.Interface but is able to add labels to the Lease.\n// The implementation is based resourclock.LeaseLock and shares some helper functions with it.\n// nolint:revive // don't rename LeaseLock to stay close to the original implementation in client-go.\ntype LeaseLock struct {\n\t// LeaseMeta should contain a Name and a Namespace of a\n\t// LeaseMeta object that the LeaderElector will attempt to lead.\n\tLeaseMeta  metav1.ObjectMeta\n\tClient     coordinationv1client.LeasesGetter\n\tLockConfig resourcelock.ResourceLockConfig\n\tLabels     map[string]string\n\tlease      *coordinationv1.Lease\n}\n\n// Get returns the election record from a Lease spec\nfunc (ll *LeaseLock) Get(ctx context.Context) (*resourcelock.LeaderElectionRecord, []byte, error) {\n\tlease, err := ll.Client.Leases(ll.LeaseMeta.Namespace).Get(ctx, ll.LeaseMeta.Name, metav1.GetOptions{})\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tll.lease = lease\n\trecord := resourcelock.LeaseSpecToLeaderElectionRecord(&ll.lease.Spec)\n\trecordByte, err := json.Marshal(*record)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn record, recordByte, nil\n}\n\n// Create attempts to create a Lease\nfunc (ll *LeaseLock) Create(ctx context.Context, ler resourcelock.LeaderElectionRecord) error {\n\tvar err error\n\tll.lease, err = ll.Client.Leases(ll.LeaseMeta.Namespace).Create(ctx, &coordinationv1.Lease{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      ll.LeaseMeta.Name,\n\t\t\tNamespace: ll.LeaseMeta.Namespace,\n\t\t\tLabels:    ll.Labels,\n\t\t},\n\t\tSpec: resourcelock.LeaderElectionRecordToLeaseSpec(&ler),\n\t}, metav1.CreateOptions{})\n\treturn err\n}\n\n// Update will update an existing Lease spec.\nfunc (ll *LeaseLock) Update(ctx context.Context, ler resourcelock.LeaderElectionRecord) error {\n\tif ll.lease == nil {\n\t\treturn errors.New(\"lease not initialized, call Get or Create first\")\n\t}\n\t// don't set labels map on ll.lease directly, otherwise we might overwrite labels managed by the sharder\n\tmergeLabels(&ll.lease.ObjectMeta, ll.Labels)\n\tll.lease.Spec = resourcelock.LeaderElectionRecordToLeaseSpec(&ler)\n\n\tlease, err := ll.Client.Leases(ll.LeaseMeta.Namespace).Update(ctx, ll.lease, metav1.UpdateOptions{})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tll.lease = lease\n\treturn nil\n}\n\n// RecordEvent does nothing, as recording events on shard leases is not meaningful.\nfunc (ll *LeaseLock) RecordEvent(string) {}\n\n// Describe is used to convert details on current resource lock\n// into a string\nfunc (ll *LeaseLock) Describe() string {\n\treturn fmt.Sprintf(\"%v/%v\", ll.LeaseMeta.Namespace, ll.LeaseMeta.Name)\n}\n\n// Identity returns the Identity of the lock\nfunc (ll *LeaseLock) Identity() string {\n\treturn ll.LockConfig.Identity\n}\n\nfunc mergeLabels(obj *metav1.ObjectMeta, labels map[string]string) {\n\tfor key, value := range labels {\n\t\tmetav1.SetMetaDataLabel(obj, key, value)\n\t}\n}\n\n// allow overwriting file system for testing purposes\nvar fsys = os.DirFS(\"/\")\n\nconst inClusterNamespacePath = \"var/run/secrets/kubernetes.io/serviceaccount/namespace\"\n\n// getInClusterNamespace determines the namespace that this binary is running in, if running in a cluster.\n// For this, it consults the ServiceAccount mount. If the binary is not running in a cluster or the pod doesn't mount a\n// ServiceAccount, it returns an error.\nfunc getInClusterNamespace() (string, error) {\n\t// Check whether the namespace file exists.\n\t// If not, we are not running in cluster so can't guess the namespace.\n\tif _, err := fs.Stat(fsys, inClusterNamespacePath); os.IsNotExist(err) {\n\t\treturn \"\", fmt.Errorf(\"not running in cluster, please specify LeaseNamespace\")\n\t} else if err != nil {\n\t\treturn \"\", fmt.Errorf(\"error checking namespace file: %w\", err)\n\t}\n\n\t// Load the namespace file and return its content\n\tnamespace, err := fs.ReadFile(fsys, inClusterNamespacePath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error reading namespace file: %w\", err)\n\t}\n\treturn string(namespace), nil\n}\n"
  },
  {
    "path": "pkg/shard/lease/lease_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage lease_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestLease(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Shard Library Lease Suite\")\n}\n"
  },
  {
    "path": "pkg/shard/lease/lease_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage lease\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"testing/fstest\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/client-go/kubernetes/fake\"\n\tcoordinationv1client \"k8s.io/client-go/kubernetes/typed/coordination/v1\"\n\t\"k8s.io/client-go/rest\"\n\t\"k8s.io/client-go/tools/leaderelection/resourcelock\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nvar _ = Describe(\"LeaseLock\", func() {\n\tconst (\n\t\tnamespace          = \"default\"\n\t\tcontrollerRingName = \"operator\"\n\t\tshardName          = \"operator-a\"\n\t)\n\n\tvar ctx context.Context\n\n\tBeforeEach(func() {\n\t\tctx = context.Background()\n\n\t\tfsys = fstest.MapFS{\n\t\t\t\"var/run/secrets/kubernetes.io/serviceaccount/namespace\": &fstest.MapFile{\n\t\t\t\tData: []byte(namespace),\n\t\t\t},\n\t\t}\n\t})\n\n\tDescribe(\"#NewResourceLock\", func() {\n\t\tvar (\n\t\t\trestConfig *rest.Config\n\n\t\t\toptions Options\n\t\t)\n\n\t\tBeforeEach(func() {\n\t\t\trestConfig = &rest.Config{}\n\n\t\t\toptions = Options{\n\t\t\t\tControllerRingName: controllerRingName,\n\t\t\t\tLeaseNamespace:     \"operator-system\",\n\t\t\t\tShardName:          shardName,\n\t\t\t}\n\t\t})\n\n\t\tIt(\"should fail if ControllerRingName is empty\", func() {\n\t\t\toptions.ControllerRingName = \"\"\n\n\t\t\tExpect(NewResourceLock(restConfig, options)).Error().To(MatchError(\"ControllerRingName is required\"))\n\t\t})\n\n\t\tIt(\"should use the configured namespace and name\", func() {\n\t\t\tresourceLock, err := NewResourceLock(restConfig, options)\n\t\t\tExpect(err).NotTo(HaveOccurred())\n\n\t\t\tleaseLock := resourceLock.(*LeaseLock)\n\t\t\tExpect(leaseLock.LeaseMeta.Namespace).To(Equal(options.LeaseNamespace))\n\t\t\tExpect(leaseLock.LeaseMeta.Name).To(Equal(options.ShardName))\n\t\t\tExpect(leaseLock.Identity()).To(Equal(leaseLock.LeaseMeta.Name), \"identity should equal the shard name\")\n\t\t})\n\n\t\tIt(\"should default the name to the hostname\", func() {\n\t\t\toptions.ShardName = \"\"\n\t\t\thostname, err := os.Hostname()\n\t\t\tExpect(err).NotTo(HaveOccurred())\n\n\t\t\tresourceLock, err := NewResourceLock(restConfig, options)\n\t\t\tExpect(err).NotTo(HaveOccurred())\n\n\t\t\tleaseLock := resourceLock.(*LeaseLock)\n\t\t\tExpect(leaseLock.LeaseMeta.Name).To(Equal(hostname))\n\t\t\tExpect(leaseLock.Identity()).To(Equal(leaseLock.LeaseMeta.Name), \"identity should equal the shard name\")\n\t\t})\n\n\t\tIt(\"should default the namespace to the in-cluster namespace\", func() {\n\t\t\toptions.LeaseNamespace = \"\"\n\n\t\t\tresourceLock, err := NewResourceLock(restConfig, options)\n\t\t\tExpect(err).NotTo(HaveOccurred())\n\n\t\t\tleaseLock := resourceLock.(*LeaseLock)\n\t\t\tExpect(leaseLock.LeaseMeta.Namespace).To(Equal(namespace))\n\t\t})\n\n\t\tIt(\"should fail if the in-cluster namespace cannot be determined\", func() {\n\t\t\toptions.LeaseNamespace = \"\"\n\t\t\tfsys = fstest.MapFS{}\n\n\t\t\tExpect(NewResourceLock(restConfig, options)).Error().To(MatchError(And(\n\t\t\t\tContainSubstring(\"not running in cluster\"),\n\t\t\t\tContainSubstring(\"please specify LeaseNamespace\"),\n\t\t\t)))\n\t\t})\n\t})\n\n\tDescribe(\"#LeaseLock\", func() {\n\t\tvar (\n\t\t\tlock       resourcelock.Interface\n\t\t\tfakeClient coordinationv1client.LeasesGetter\n\n\t\t\tlease *coordinationv1.Lease\n\t\t)\n\n\t\tBeforeEach(func() {\n\t\t\tvar err error\n\t\t\tlock, err = NewResourceLock(&rest.Config{}, Options{\n\t\t\t\tControllerRingName: controllerRingName,\n\t\t\t\tLeaseNamespace:     namespace,\n\t\t\t\tShardName:          shardName,\n\t\t\t})\n\t\t\tExpect(err).NotTo(HaveOccurred())\n\n\t\t\tfakeClient = fake.NewClientset().CoordinationV1()\n\t\t\tlock.(*LeaseLock).Client = fakeClient\n\n\t\t\tlease = &coordinationv1.Lease{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tNamespace: namespace,\n\t\t\t\t\tName:      shardName,\n\t\t\t\t},\n\t\t\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\t\t\tHolderIdentity: ptr.To(shardName),\n\t\t\t\t},\n\t\t\t}\n\t\t\tExpect(fakeClient.Leases(lease.Namespace).Create(ctx, lease, metav1.CreateOptions{})).Error().To(Succeed())\n\t\t})\n\n\t\tDescribe(\"#Get\", func() {\n\t\t\tIt(\"should return NotFound if the lease does not exist\", func() {\n\t\t\t\tExpect(fakeClient.Leases(lease.Namespace).Delete(ctx, lease.Name, metav1.DeleteOptions{})).To(Succeed())\n\t\t\t\tExpect(lock.Get(ctx)).Error().To(BeNotFoundError())\n\t\t\t})\n\n\t\t\tIt(\"should return the existing lease\", func() {\n\t\t\t\trecord, _, err := lock.Get(ctx)\n\t\t\t\tExpect(err).NotTo(HaveOccurred())\n\t\t\t\tExpect(record).NotTo(BeNil())\n\t\t\t\tExpect(record.HolderIdentity).To(Equal(*lease.Spec.HolderIdentity))\n\t\t\t})\n\t\t})\n\n\t\tDescribe(\"#Create\", func() {\n\t\t\tIt(\"should create the lease if it does not exist\", func() {\n\t\t\t\tExpect(fakeClient.Leases(lease.Namespace).Delete(ctx, lease.Name, metav1.DeleteOptions{})).To(Succeed())\n\n\t\t\t\tExpect(lock.Create(ctx, resourcelock.LeaderElectionRecord{\n\t\t\t\t\tHolderIdentity: \"foo\",\n\t\t\t\t})).To(Succeed())\n\n\t\t\t\tExpect(fakeClient.Leases(lease.Namespace).Get(ctx, lease.Name, metav1.GetOptions{})).To(And(\n\t\t\t\t\tHaveField(\"ObjectMeta\", And(\n\t\t\t\t\t\tHaveField(\"Namespace\", Equal(namespace)),\n\t\t\t\t\t\tHaveField(\"Name\", Equal(shardName)),\n\t\t\t\t\t\tHaveField(\"Labels\", Equal(map[string]string{\n\t\t\t\t\t\t\t\"alpha.sharding.timebertt.dev/controllerring\": controllerRingName,\n\t\t\t\t\t\t})),\n\t\t\t\t\t)),\n\t\t\t\t\tHaveField(\"Spec.HolderIdentity\", Equal(ptr.To(\"foo\"))),\n\t\t\t\t))\n\t\t\t})\n\t\t})\n\n\t\tDescribe(\"#Update\", func() {\n\t\t\tIt(\"should fail if lock is not initialized yet\", func() {\n\t\t\t\tExpect(lock.Update(ctx, resourcelock.LeaderElectionRecord{\n\t\t\t\t\tHolderIdentity: \"foo\",\n\t\t\t\t})).To(MatchError(ContainSubstring(\"not initialized\")))\n\t\t\t})\n\n\t\t\tIt(\"should update the lease\", func() {\n\t\t\t\tExpect(lock.Get(ctx)).Error().To(Succeed())\n\n\t\t\t\tExpect(lock.Update(ctx, resourcelock.LeaderElectionRecord{\n\t\t\t\t\tHolderIdentity: \"foo\",\n\t\t\t\t})).To(Succeed())\n\n\t\t\t\tExpect(fakeClient.Leases(lease.Namespace).Get(ctx, lease.Name, metav1.GetOptions{})).To(And(\n\t\t\t\t\tHaveField(\"ObjectMeta\", And(\n\t\t\t\t\t\tHaveField(\"Namespace\", Equal(namespace)),\n\t\t\t\t\t\tHaveField(\"Name\", Equal(shardName)),\n\t\t\t\t\t\tHaveField(\"Labels\", Equal(map[string]string{\n\t\t\t\t\t\t\t\"alpha.sharding.timebertt.dev/controllerring\": controllerRingName,\n\t\t\t\t\t\t})),\n\t\t\t\t\t)),\n\t\t\t\t\tHaveField(\"Spec.HolderIdentity\", Equal(ptr.To(\"foo\"))),\n\t\t\t\t))\n\t\t\t})\n\n\t\t\tIt(\"should keep externally managed labels\", func() {\n\t\t\t\tmetav1.SetMetaDataLabel(&lease.ObjectMeta, \"foo\", \"bar\")\n\t\t\t\tExpect(fakeClient.Leases(lease.Namespace).Update(ctx, lease, metav1.UpdateOptions{})).Error().To(Succeed())\n\n\t\t\t\tExpect(lock.Get(ctx)).Error().To(Succeed())\n\n\t\t\t\tExpect(lock.Update(ctx, resourcelock.LeaderElectionRecord{\n\t\t\t\t\tHolderIdentity: \"foo\",\n\t\t\t\t})).To(Succeed())\n\n\t\t\t\tExpect(fakeClient.Leases(lease.Namespace).Get(ctx, lease.Name, metav1.GetOptions{})).To(\n\t\t\t\t\tHaveField(\"ObjectMeta.Labels\", Equal(map[string]string{\n\t\t\t\t\t\t\"foo\": \"bar\",\n\t\t\t\t\t\t\"alpha.sharding.timebertt.dev/controllerring\": controllerRingName,\n\t\t\t\t\t})),\n\t\t\t\t)\n\t\t\t})\n\t\t})\n\n\t\tDescribe(\"#RecordEvent\", func() {\n\t\t\tIt(\"should do nothing\", func() {\n\t\t\t\tlock.RecordEvent(\"foo\")\n\t\t\t})\n\t\t})\n\n\t\tDescribe(\"#Describe\", func() {\n\t\t\tIt(\"should return the lease key\", func() {\n\t\t\t\tExpect(lock.Describe()).To(Equal(client.ObjectKeyFromObject(lease).String()))\n\t\t\t})\n\t\t})\n\n\t\tDescribe(\"#Identity()\", func() {\n\t\t\tIt(\"should return the lease name\", func() {\n\t\t\t\tExpect(lock.Identity()).To(Equal(lease.Name))\n\t\t\t})\n\t\t})\n\t})\n\n\tDescribe(\"#getInClusterNamespace\", func() {\n\t\tIt(\"should fail because namespace file does not exist\", func() {\n\t\t\tfsys = fstest.MapFS{}\n\n\t\t\tExpect(getInClusterNamespace()).Error().To(MatchError(ContainSubstring(\"not running in cluster\")))\n\t\t})\n\n\t\tIt(\"should return content of namespace file\", func() {\n\t\t\tExpect(getInClusterNamespace()).To(Equal(namespace))\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/sharding/consistenthash/benchmark_test.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage consistenthash\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"testing\"\n)\n\nfunc TestDistribution(t *testing.T) {\n\tring := New(DefaultHash, DefaultTokensPerNode)\n\n\thosts := generateHostnames(10)\n\tdist := make(map[string]float64, len(hosts))\n\tring.AddNodes(hosts...)\n\tfor _, host := range hosts {\n\t\tdist[host] = 0\n\t}\n\n\t// fmt.Println(\"Virtual Nodes:\")\n\tlast := ring.tokens[len(ring.tokens)-1]\n\tfor _, token := range ring.tokens {\n\t\tnode := ring.tokenToNode[token]\n\t\tpercentage := float64(token-last) / math.MaxUint64\n\t\tdist[node] += percentage\n\n\t\t// fmt.Printf(\"\\t%016x (%.5f): %.5f -> %s\\n\", token, float64(token)/math.MaxUint64, percentage, node)\n\t\tlast = token\n\t}\n\n\tfmt.Println(\"Nodes distribution:\")\n\tfor _, host := range hosts {\n\t\tfmt.Printf(\"\\t%s: %.5f\\n\", host, dist[host])\n\t}\n}\n\nfunc generateHostnames(n int) []string {\n\thosts := make([]string, n)\n\tfor i := range hosts {\n\t\thost := fmt.Sprintf(\"10.42.0.%d\", i)\n\t\thosts[i] = host\n\t}\n\treturn hosts\n}\n\nfunc benchmarkRing(nodes int, tokensPerNode int, b *testing.B) {\n\thosts := generateHostnames(nodes)\n\tb.ResetTimer()\n\n\tfor n := 0; n < b.N; n++ {\n\t\tring := New(DefaultHash, tokensPerNode, hosts...)\n\t\tring.Hash(\"Website.webhosting.timebertt.dev/project-foo/homepage\")\n\t}\n}\n\nfunc BenchmarkRing3_100(b *testing.B)   { benchmarkRing(3, 100, b) }\nfunc BenchmarkRing3_1000(b *testing.B)  { benchmarkRing(3, 1000, b) }\nfunc BenchmarkRing5_100(b *testing.B)   { benchmarkRing(5, 100, b) }\nfunc BenchmarkRing5_1000(b *testing.B)  { benchmarkRing(5, 1000, b) }\nfunc BenchmarkRing10_100(b *testing.B)  { benchmarkRing(10, 100, b) }\nfunc BenchmarkRing10_1000(b *testing.B) { benchmarkRing(10, 1000, b) }\n"
  },
  {
    "path": "pkg/sharding/consistenthash/consistenthash_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage consistenthash_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestConsistentHash(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Consistent Hash Suite\")\n}\n"
  },
  {
    "path": "pkg/sharding/consistenthash/ring.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage consistenthash\n\nimport (\n\t\"slices\"\n\t\"strconv\"\n\n\t\"github.com/cespare/xxhash/v2\"\n)\n\n// Hash is a function computing a 64-bit digest.\ntype Hash func(data string) uint64\n\n// DefaultHash is the default Hash used by Ring.\nvar DefaultHash Hash = xxhash.Sum64String\n\n// DefaultTokensPerNode is the default number of virtual nodes per node.\nconst DefaultTokensPerNode = 100\n\n// New creates a new hash ring with the given configuration and adds the given nodes.\n// The given Hash (or DefaultHash if nil) is used to hash nodes and keys (strings).\n// Each node is assigned tokensPerNode tokens (or DefaultTokensPerNode if <= 0) – aka. virtual nodes – for a more\n// uniform key distribution.\nfunc New(hash Hash, tokensPerNode int, initialNodes ...string) *Ring {\n\tif hash == nil {\n\t\thash = DefaultHash\n\t}\n\tif tokensPerNode <= 0 {\n\t\ttokensPerNode = DefaultTokensPerNode\n\t}\n\n\tnumTokens := len(initialNodes) * tokensPerNode\n\tr := &Ring{\n\t\thash:          hash,\n\t\ttokensPerNode: tokensPerNode,\n\n\t\ttokens:      make([]uint64, 0, numTokens),\n\t\ttokenToNode: make(map[uint64]string, numTokens),\n\t}\n\tr.AddNodes(initialNodes...)\n\treturn r\n}\n\n// Ring implements consistent hashing, aka. ring hash (not thread-safe).\n// It hashes nodes and keys (strings) onto a ring of tokens. Keys are mapped to the next token (node) on the ring.\n// Nodes cannot be removed. Instantiate a new Ring instead.\ntype Ring struct {\n\thash          Hash\n\ttokensPerNode int\n\n\ttokens      []uint64\n\ttokenToNode map[uint64]string\n}\n\n// IsEmpty returns true if there are no nodes in this Ring.\nfunc (r *Ring) IsEmpty() bool {\n\treturn len(r.tokens) == 0\n}\n\n// AddNodes adds hash tokens for the given nodes to this Ring.\nfunc (r *Ring) AddNodes(nodes ...string) {\n\tfor _, node := range nodes {\n\t\tfor i := 0; i < r.tokensPerNode; i++ {\n\t\t\tt := r.hash(node + strconv.FormatInt(int64(i), 10))\n\t\t\tr.tokens = append(r.tokens, t)\n\t\t\tr.tokenToNode[t] = node\n\t\t}\n\t}\n\n\t// sort all tokens on the ring for binary searches\n\tslices.Sort(r.tokens)\n}\n\n// Hash hashes the given key onto the ring of tokens and returns the node that belongs to the next token on the ring.\nfunc (r *Ring) Hash(key string) string {\n\tif r.IsEmpty() {\n\t\treturn \"\"\n\t}\n\n\t// Hash key and find the next virtual node on the ring\n\th := r.hash(key)\n\ti, _ := slices.BinarySearch(r.tokens, h)\n\n\t// walked the whole ring, next virtual node is the first one\n\tif i == len(r.tokens) {\n\t\ti = 0\n\t}\n\n\treturn r.tokenToNode[r.tokens[i]]\n}\n"
  },
  {
    "path": "pkg/sharding/consistenthash/ring_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage consistenthash_test\n\nimport (\n\t\"strings\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/consistenthash\"\n)\n\nvar _ = Describe(\"Ring\", func() {\n\tDescribe(\"#New\", func() {\n\t\tIt(\"should initialize a new Ring\", func() {\n\t\t\tring := New(nil, 0, \"foo\")\n\t\t\tExpect(ring).NotTo(BeNil())\n\t\t\tExpect(ring.IsEmpty()).To(BeFalse())\n\t\t})\n\t})\n\n\tDescribe(\"#IsEmpty\", func() {\n\t\tIt(\"should true if there are no nodes\", func() {\n\t\t\tring := New(nil, 0)\n\t\t\tExpect(ring.IsEmpty()).To(BeTrue())\n\t\t\tring.AddNodes(\"foo\")\n\t\t\tExpect(ring.IsEmpty()).To(BeFalse())\n\t\t})\n\t})\n\n\tDescribe(\"#Hash\", func() {\n\t\tIt(\"should use the configured hash function\", func() {\n\t\t\tring := New(func(data string) uint64 {\n\t\t\t\tif strings.HasPrefix(data, \"foo\") {\n\t\t\t\t\t// map all foo* nodes and keys to 1\n\t\t\t\t\treturn 1\n\t\t\t\t}\n\t\t\t\treturn 2\n\t\t\t}, 1, \"foo\", \"bar\")\n\n\t\t\tExpect(ring.Hash(\"foo\")).To(Equal(\"foo\"))\n\t\t\tExpect(ring.Hash(\"bar\")).To(Equal(\"bar\"))\n\t\t\tExpect(ring.Hash(\"baz\")).To(Equal(\"bar\"))\n\t\t})\n\n\t\tIt(\"should use the default hash function\", func() {\n\t\t\tring := New(nil, 0, \"foo\", \"bar\")\n\n\t\t\tExpect(ring.Hash(\"1\")).NotTo(Equal(ring.Hash(\"10\")))\n\t\t})\n\n\t\tIt(\"should return the empty string if there are no nodes\", func() {\n\t\t\tring := New(nil, 0)\n\n\t\t\tExpect(ring.Hash(\"foo\")).To(BeEmpty())\n\t\t})\n\n\t\tIt(\"should return the first node when walking the whole ring\", func() {\n\t\t\tring := New(func(data string) uint64 {\n\t\t\t\tif strings.HasPrefix(data, \"foo\") {\n\t\t\t\t\t// map all foo* nodes and keys to 1\n\t\t\t\t\treturn 1\n\t\t\t\t}\n\t\t\t\tif strings.HasPrefix(data, \"bar\") {\n\t\t\t\t\t// map all bar* nodes and keys to 1\n\t\t\t\t\treturn 2\n\t\t\t\t}\n\t\t\t\treturn 3\n\t\t\t}, 1, \"foo\", \"bar\")\n\n\t\t\tExpect(ring.Hash(\"foo\")).To(Equal(\"foo\"))\n\t\t\tExpect(ring.Hash(\"bar\")).To(Equal(\"bar\"))\n\t\t\tExpect(ring.Hash(\"baz\")).To(Equal(\"foo\"))\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/sharding/handler/controllerring.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage handler\n\nimport (\n\t\"context\"\n\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/handler\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n)\n\nvar handlerLog = logf.Log.WithName(\"handler\")\n\n// MapControllerRingToLeases maps a ControllerRing to all matching shard leases.\nfunc MapControllerRingToLeases(reader client.Reader) handler.MapFunc {\n\treturn func(ctx context.Context, obj client.Object) []reconcile.Request {\n\t\tcontrollerRing, ok := obj.(*shardingv1alpha1.ControllerRing)\n\t\tif !ok {\n\t\t\treturn nil\n\t\t}\n\n\t\tleaseList := &coordinationv1.LeaseList{}\n\t\tif err := reader.List(ctx, leaseList, client.MatchingLabelsSelector{Selector: controllerRing.LeaseSelector()}); err != nil {\n\t\t\thandlerLog.Error(err, \"failed listing Leases for ControllerRing\", \"controllerRing\", client.ObjectKeyFromObject(controllerRing))\n\t\t\treturn nil\n\t\t}\n\n\t\trequests := make([]reconcile.Request, 0, len(leaseList.Items))\n\t\tfor _, lease := range leaseList.Items {\n\t\t\trequests = append(requests, reconcile.Request{NamespacedName: client.ObjectKeyFromObject(&lease)})\n\t\t}\n\n\t\treturn requests\n\t}\n}\n"
  },
  {
    "path": "pkg/sharding/handler/controllerring_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage handler_test\n\nimport (\n\t\"context\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\tfakeclient \"sigs.k8s.io/controller-runtime/pkg/client/fake\"\n\t\"sigs.k8s.io/controller-runtime/pkg/handler\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/handler\"\n)\n\nvar _ = Describe(\"ControllerRing\", func() {\n\tvar (\n\t\tctx context.Context\n\n\t\tfakeClient client.Client\n\t)\n\n\tBeforeEach(func() {\n\t\tctx = context.Background()\n\n\t\tfakeClient = fakeclient.NewFakeClient()\n\t})\n\n\tDescribe(\"#MapControllerRingToLeases\", func() {\n\t\tvar (\n\t\t\tmapFunc handler.MapFunc\n\n\t\t\tobj *shardingv1alpha1.ControllerRing\n\t\t)\n\n\t\tBeforeEach(func() {\n\t\t\tmapFunc = MapControllerRingToLeases(fakeClient)\n\n\t\t\tobj = &shardingv1alpha1.ControllerRing{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName: \"foo\",\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tlease := &coordinationv1.Lease{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName:      \"foo-1\",\n\t\t\t\t\tNamespace: \"foo-system\",\n\t\t\t\t\tLabels: map[string]string{\n\t\t\t\t\t\t\"alpha.sharding.timebertt.dev/controllerring\": \"foo\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t\tExpect(fakeClient.Create(ctx, lease.DeepCopy())).To(Succeed())\n\n\t\t\tlease.Name = \"foo-2\"\n\t\t\tExpect(fakeClient.Create(ctx, lease.DeepCopy())).To(Succeed())\n\n\t\t\tlease.Name = \"foo-3\"\n\t\t\tlease.Labels[\"alpha.sharding.timebertt.dev/controllerring\"] = \"bar\"\n\t\t\tExpect(fakeClient.Create(ctx, lease.DeepCopy())).To(Succeed())\n\n\t\t\tlease.Name = \"foo-4\"\n\t\t\tlease.Labels = nil\n\t\t\tExpect(fakeClient.Create(ctx, lease.DeepCopy())).To(Succeed())\n\t\t})\n\n\t\tIt(\"should ignore other object kinds\", func() {\n\t\t\tExpect(mapFunc(ctx, &corev1.Pod{})).To(BeEmpty())\n\t\t})\n\n\t\tIt(\"should return requests for all matching leases\", func() {\n\t\t\tExpect(mapFunc(ctx, obj)).To(ConsistOf(\n\t\t\t\treconcile.Request{NamespacedName: types.NamespacedName{Namespace: \"foo-system\", Name: \"foo-1\"}},\n\t\t\t\treconcile.Request{NamespacedName: types.NamespacedName{Namespace: \"foo-system\", Name: \"foo-2\"}},\n\t\t\t))\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/sharding/handler/handler_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage handler_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestHandler(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Sharding Handlers Suite\")\n}\n"
  },
  {
    "path": "pkg/sharding/handler/lease.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage handler\n\nimport (\n\t\"context\"\n\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n)\n\n// MapLeaseToControllerRing maps a shard lease to its ControllerRing.\nfunc MapLeaseToControllerRing(_ context.Context, obj client.Object) []reconcile.Request {\n\tring := obj.GetLabels()[shardingv1alpha1.LabelControllerRing]\n\tif ring == \"\" {\n\t\treturn nil\n\t}\n\n\treturn []reconcile.Request{{NamespacedName: client.ObjectKey{Name: ring}}}\n}\n"
  },
  {
    "path": "pkg/sharding/handler/lease_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage handler_test\n\nimport (\n\t\"context\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/handler\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/handler\"\n)\n\nvar _ = Describe(\"Lease\", func() {\n\tvar ctx context.Context\n\n\tBeforeEach(func() {\n\t\tctx = context.Background()\n\t})\n\n\tDescribe(\"#MapLeaseToControllerRing\", func() {\n\t\tvar (\n\t\t\tmapFunc handler.MapFunc\n\n\t\t\tobj *coordinationv1.Lease\n\t\t)\n\n\t\tBeforeEach(func() {\n\t\t\tmapFunc = MapLeaseToControllerRing\n\n\t\t\tobj = &coordinationv1.Lease{}\n\t\t})\n\n\t\tIt(\"should ignore unlabelled leases\", func() {\n\t\t\tExpect(mapFunc(ctx, obj)).To(BeEmpty())\n\t\t})\n\n\t\tIt(\"should ignore leases with empty label\", func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"alpha.sharding.timebertt.dev/controllerring\", \"\")\n\t\t\tExpect(mapFunc(ctx, obj)).To(BeEmpty())\n\t\t})\n\n\t\tIt(\"should correctly map leases with present label\", func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"alpha.sharding.timebertt.dev/controllerring\", \"foo\")\n\t\t\tExpect(mapFunc(ctx, obj)).To(ConsistOf(reconcile.Request{NamespacedName: client.ObjectKey{Name: \"foo\"}}))\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/sharding/key/key.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage key\n\nimport (\n\t\"fmt\"\n\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n)\n\n// FuncForResource returns the key function that maps the given resource or its controller depending on whether\n// the resource is listed as a resource or controlled resource in the given ring.\nfunc FuncForResource(gr metav1.GroupResource, ring *shardingv1alpha1.ControllerRing) (Func, error) {\n\tringResources := sets.New[metav1.GroupResource]()\n\tcontrolledResources := sets.New[metav1.GroupResource]()\n\n\tfor _, ringResource := range ring.Spec.Resources {\n\t\tringResources.Insert(ringResource.GroupResource)\n\n\t\tfor _, controlledResource := range ringResource.ControlledResources {\n\t\t\tcontrolledResources.Insert(controlledResource)\n\t\t}\n\t}\n\n\tswitch {\n\tcase ringResources.Has(gr):\n\t\treturn ForObject, nil\n\tcase controlledResources.Has(gr):\n\t\treturn ForController, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"object's resource %q was not found in ControllerRing\", gr.String())\n}\n\n// Func maps objects to hash keys.\n// It returns an error if the prerequisites for sharding the given object are not fulfilled.\n// If the returned key is empty, the object should not be assigned.\ntype Func func(client.Object) (string, error)\n\n// ForObject returns a ring key for the given object itself.\n// It needs the TypeMeta (GVK) to be set, which is not set on objects after decoding by default.\nfunc ForObject(obj client.Object) (string, error) {\n\t// We can't use the object's UID, as it is unset during admission for CREATE requests.\n\t// Instead, we need to calculate a unique ID ourselves. The ID has this pattern (see forMetadata):\n\t//  group/version/kind/namespace/name\n\t// With this, different object instances with the same name will use the same hash key, which sounds acceptable.\n\t// We can only use fields that are also present in owner references as we need to assign owners and ownees to the same\n\t// shard. E.g., we can't use generateName.\n\n\tgvk := obj.GetObjectKind().GroupVersionKind()\n\tif gvk.Empty() {\n\t\treturn \"\", fmt.Errorf(\"apiVersion and kind must not be empty\")\n\t}\n\n\tif obj.GetName() == \"\" {\n\t\tif obj.GetGenerateName() != \"\" {\n\t\t\t// If generateName is used, name is unset during admission for CREATE requests.\n\t\t\t// We can't support assigning such objects during admission because we will not be able to calculate a unique\n\t\t\t// object ID that we can also reconstruct later on for owned objects just by looking at the object itself.\n\t\t\t// We could use a cache lookup though, but this would restrict scalability of the sharding solution again.\n\t\t\t// Generally, this tradeoff seems acceptable, as generateName is mostly used on owned objects, but rarely the\n\t\t\t// owner itself. In such case, ForController will be used instead, which doesn't care about the object's own\n\t\t\t// name but only that of the owner.\n\t\t\t// If generateName is used nevertheless, respond with a proper error.\n\t\t\t// We could assign the object after creation, however we can't use a watch cache because of the mentioned\n\t\t\t// scalability limitations. A possible solution could only do some optimistic delayed enqueuing.\n\t\t\treturn \"\", fmt.Errorf(\"generateName is not supported on ring resources that are not controlled by another resource\")\n\t\t}\n\n\t\treturn \"\", fmt.Errorf(\"name must not be empty\")\n\t}\n\n\t// Namespace can be empty for cluster-scoped resources. Only check the name field as an optimistic check for\n\t// preventing wrong usage of the function.\n\treturn forMetadata(gvk.Group, gvk.Kind, obj.GetNamespace(), obj.GetName()), nil\n}\n\n// ForController returns a ring key for the controller of the given object.\n// It returns an empty key if the object doesn't have an ownerReference with controller=true\".\nfunc ForController(obj client.Object) (string, error) {\n\tref := metav1.GetControllerOf(obj)\n\tif ref == nil {\n\t\treturn \"\", nil\n\t}\n\n\tif ref.APIVersion == \"\" {\n\t\treturn \"\", fmt.Errorf(\"apiVersion of controller reference must not be empty\")\n\t}\n\tif ref.Kind == \"\" {\n\t\treturn \"\", fmt.Errorf(\"kind of controller reference must not be empty\")\n\t}\n\tif ref.Name == \"\" {\n\t\treturn \"\", fmt.Errorf(\"name of controller reference must not be empty\")\n\t}\n\n\tgv, err := schema.ParseGroupVersion(ref.APIVersion)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid apiVersion of controller reference: %w\", err)\n\t}\n\n\treturn forMetadata(gv.Group, ref.Kind, obj.GetNamespace(), ref.Name), nil\n}\n\nfunc forMetadata(group, kind, namespace, name string) string {\n\treturn group + \"/\" + kind + \"/\" + namespace + \"/\" + name\n}\n"
  },
  {
    "path": "pkg/sharding/key/key_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage key_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestKey(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Sharding Key Suite\")\n}\n"
  },
  {
    "path": "pkg/sharding/key/key_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage key_test\n\nimport (\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/ptr\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/key\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nvar _ = Describe(\"#FuncForResource\", func() {\n\tvar controllerRing *shardingv1alpha1.ControllerRing\n\n\tBeforeEach(func() {\n\t\tcontrollerRing = &shardingv1alpha1.ControllerRing{\n\t\t\tSpec: shardingv1alpha1.ControllerRingSpec{\n\t\t\t\tResources: []shardingv1alpha1.RingResource{\n\t\t\t\t\t{\n\t\t\t\t\t\tGroupResource: metav1.GroupResource{\n\t\t\t\t\t\t\tGroup:    \"operator\",\n\t\t\t\t\t\t\tResource: \"foo\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tControlledResources: []metav1.GroupResource{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tGroup:    \"operator\",\n\t\t\t\t\t\t\t\tResource: \"controlled\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tResource: \"foo\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tGroupResource: metav1.GroupResource{\n\t\t\t\t\t\t\tResource: \"foo\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t})\n\n\tIt(\"should return an error if the resource is not part of the ring\", func() {\n\t\tExpect(FuncForResource(metav1.GroupResource{\n\t\t\tResource: \"bar\",\n\t\t}, controllerRing)).Error().To(\n\t\t\tMatchError(ContainSubstring(\"not found\")),\n\t\t)\n\t})\n\n\tIt(\"should return ForObject if the resource is a main resource of the ring\", func() {\n\t\tExpect(FuncForResource(metav1.GroupResource{\n\t\t\tGroup:    \"operator\",\n\t\t\tResource: \"foo\",\n\t\t}, controllerRing)).To(\n\t\t\tBeFunc(ForObject),\n\t\t)\n\t})\n\n\tIt(\"should return ForController if the resource is a controlled resource of the ring\", func() {\n\t\tExpect(FuncForResource(metav1.GroupResource{\n\t\t\tGroup:    \"operator\",\n\t\t\tResource: \"controlled\",\n\t\t}, controllerRing)).To(\n\t\t\tBeFunc(ForController),\n\t\t)\n\t})\n\n\tIt(\"should return ForObject if the resource is a main and controlled resource of the ring\", func() {\n\t\tExpect(FuncForResource(metav1.GroupResource{\n\t\t\tResource: \"foo\",\n\t\t}, controllerRing)).To(\n\t\t\tBeFunc(ForObject),\n\t\t)\n\t})\n})\n\nvar _ = Describe(\"#ForObject\", func() {\n\tvar obj *appsv1.Deployment\n\n\tBeforeEach(func() {\n\t\tobj = &appsv1.Deployment{}\n\t\tobj.GetObjectKind().SetGroupVersionKind(appsv1.SchemeGroupVersion.WithKind(\"Deployment\"))\n\t\tobj.Name = \"foo\"\n\t\tobj.Namespace = \"bar\"\n\t})\n\n\tIt(\"should return an error if the object has no TypeMeta\", func() {\n\t\tExpect(ForObject(&appsv1.Deployment{})).Error().To(MatchError(\"apiVersion and kind must not be empty\"))\n\t})\n\n\tIt(\"should return an error if the object has no name\", func() {\n\t\tobj.Name = \"\"\n\t\tExpect(ForObject(obj)).Error().To(MatchError(\"name must not be empty\"))\n\n\t\tobj.GenerateName = \"foo-\"\n\t\tExpect(ForObject(obj)).Error().To(MatchError(ContainSubstring(\"generateName is not supported\")))\n\t})\n\n\tIt(\"should return the object's hash key\", func() {\n\t\tExpect(ForObject(obj)).To(Equal(\"apps/Deployment/bar/foo\"))\n\t})\n})\n\nvar _ = Describe(\"#ForController\", func() {\n\tvar obj *appsv1.Deployment\n\n\tBeforeEach(func() {\n\t\tobj = &appsv1.Deployment{}\n\t\tobj.SetOwnerReferences([]metav1.OwnerReference{\n\t\t\t{\n\t\t\t\tAPIVersion: \"other/v1\",\n\t\t\t\tKind:       \"Bar\",\n\t\t\t\tName:       \"owner-but-not-controller\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tAPIVersion: \"operator/v1\",\n\t\t\t\tKind:       \"Foo\",\n\t\t\t\tName:       \"foo\",\n\t\t\t\tController: ptr.To(true),\n\t\t\t},\n\t\t})\n\t\tobj.Namespace = \"bar\"\n\t})\n\n\tIt(\"should return an empty key if the object has no controller ref\", func() {\n\t\tExpect(ForController(&appsv1.Deployment{})).To(BeEmpty())\n\n\t\tobj.OwnerReferences[1].Controller = nil\n\t\tExpect(ForController(obj)).To(BeEmpty())\n\t})\n\n\tIt(\"should return an error if the controller ref has no apiVersion\", func() {\n\t\tobj.OwnerReferences[1].APIVersion = \"\"\n\t\tExpect(ForController(obj)).Error().To(MatchError(\"apiVersion of controller reference must not be empty\"))\n\t})\n\n\tIt(\"should return an error if the controller ref has no kind\", func() {\n\t\tobj.OwnerReferences[1].Kind = \"\"\n\t\tExpect(ForController(obj)).Error().To(MatchError(\"kind of controller reference must not be empty\"))\n\t})\n\n\tIt(\"should return an error if the controller ref has no name\", func() {\n\t\tobj.OwnerReferences[1].Name = \"\"\n\t\tExpect(ForController(obj)).Error().To(MatchError(\"name of controller reference must not be empty\"))\n\t})\n\n\tIt(\"should return an error if the controller ref has an invalid apiVersion\", func() {\n\t\tobj.OwnerReferences[1].APIVersion = \"foo/bar/v1\"\n\t\tExpect(ForController(obj)).Error().To(MatchError(ContainSubstring(\"invalid apiVersion of controller reference\")))\n\t})\n\n\tIt(\"should return the controller's hash key\", func() {\n\t\tExpect(ForController(obj)).To(Equal(\"operator/Foo/bar/foo\"))\n\t})\n})\n"
  },
  {
    "path": "pkg/sharding/leases/leases_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage leases_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestLeases(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Leases Suite\")\n}\n"
  },
  {
    "path": "pkg/sharding/leases/shards.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage leases\n\nimport (\n\t\"time\"\n\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n)\n\n// Shard represents a single shard in a ring of controller instances.\ntype Shard struct {\n\t// ID is the ID of this Shard, i.e., the name of the Lease object.\n\tID string\n\t// State is the current state of this shard based on the times and durations of the Lease object.\n\tState ShardState\n\t// Times holds the parsed times and durations of the Lease object.\n\tTimes Times\n}\n\n// Shards is a list of Shards.\n// This could also be a map, but a slice is deterministic in order. The methods returning a list are called way more\n// frequently than a lookup using ByID.\ntype Shards []Shard\n\n// ByID returns the Shard with the given ID from the list of Shards.\nfunc (s Shards) ByID(id string) Shard {\n\tfor _, shard := range s {\n\t\tif shard.ID == id {\n\t\t\treturn shard\n\t\t}\n\t}\n\n\treturn Shard{}\n}\n\n// AvailableShards returns the subset of available Shards as determined by IsAvailable.\nfunc (s Shards) AvailableShards() Shards {\n\tshards := make(Shards, 0, len(s))\n\tfor _, shard := range s {\n\t\tif shard.State.IsAvailable() {\n\t\t\tshards = append(shards, shard)\n\t\t}\n\t}\n\n\treturn shards\n}\n\n// IDs returns the list of Shard IDs.\nfunc (s Shards) IDs() []string {\n\tids := make([]string, len(s))\n\tfor i, shard := range s {\n\t\tids[i] = shard.ID\n\t}\n\n\treturn ids\n}\n\n// ToShards takes a list of Lease objects and transforms them to a list of Shards.\nfunc ToShards(leases []coordinationv1.Lease, now time.Time) Shards {\n\tshards := make(Shards, 0, len(leases))\n\tfor _, lease := range leases {\n\t\tshards = append(shards, ToShard(&lease, now))\n\t}\n\treturn shards\n}\n\n// ToShard takes a Lease object and transforms it to a Shard.\nfunc ToShard(lease *coordinationv1.Lease, now time.Time) Shard {\n\ttimes := ToTimes(lease, now)\n\treturn Shard{\n\t\tID:    lease.GetName(),\n\t\tTimes: times,\n\t\tState: toState(lease, times),\n\t}\n}\n"
  },
  {
    "path": "pkg/sharding/leases/shards_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage leases_test\n\nimport (\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\t\"github.com/onsi/gomega/gstruct\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/ptr\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n)\n\nvar _ = Describe(\"Shards\", func() {\n\tDescribe(\"#ByID\", func() {\n\t\tIt(\"should return the matching shard\", func() {\n\t\t\tshards := Shards{\n\t\t\t\t{ID: \"shard-1\"},\n\t\t\t\t{ID: \"shard-2\"},\n\t\t\t\t{ID: \"shard-3\"},\n\t\t\t}\n\t\t\tExpect(shards.ByID(\"shard-2\").ID).To(Equal(\"shard-2\"))\n\t\t})\n\n\t\tIt(\"should return a zero shard if the ID has not been found\", func() {\n\t\t\tExpect(Shards{{ID: \"shard-1\"}}.ByID(\"shard-2\").ID).To(BeZero())\n\t\t\tExpect(Shards{}.ByID(\"shard-2\").ID).To(BeZero())\n\t\t\tExpect(Shards(nil).ByID(\"shard-2\").ID).To(BeZero())\n\t\t})\n\t})\n\n\tDescribe(\"#AvailableShards\", func() {\n\t\tIt(\"should return the available shards\", func() {\n\t\t\tshards := Shards{\n\t\t\t\t{ID: \"shard-1\", State: Ready},\n\t\t\t\t{ID: \"shard-2\", State: Expired},\n\t\t\t\t{ID: \"shard-3\", State: Uncertain},\n\t\t\t\t{ID: \"shard-4\", State: Dead},\n\t\t\t\t{ID: \"shard-5\", State: Orphaned},\n\t\t\t}\n\t\t\tExpect(shards.AvailableShards().IDs()).To(ConsistOf(\"shard-1\", \"shard-2\", \"shard-3\"))\n\t\t})\n\t})\n\n\tDescribe(\"#IDs\", func() {\n\t\tIt(\"should return the shard IDs\", func() {\n\t\t\tshards := Shards{\n\t\t\t\t{ID: \"shard-1\"},\n\t\t\t\t{ID: \"shard-2\"},\n\t\t\t}\n\t\t\tExpect(shards.IDs()).To(ConsistOf(\"shard-1\", \"shard-2\"))\n\t\t})\n\t})\n\n\tDescribe(\"#ToShards\", func() {\n\t\tvar (\n\t\t\tnow   time.Time\n\t\t\tlease *coordinationv1.Lease\n\t\t)\n\n\t\tBeforeEach(func() {\n\t\t\tnow = time.Now()\n\n\t\t\tlease = &coordinationv1.Lease{\n\t\t\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\t\t\tHolderIdentity:       ptr.To(\"shard\"),\n\t\t\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(now.Add(-2 * time.Minute))),\n\t\t\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(now.Add(-2 * time.Second))),\n\t\t\t\t},\n\t\t\t}\n\t\t})\n\n\t\tIt(\"should correctly transform the lease objects\", func() {\n\t\t\tleases := make([]coordinationv1.Lease, 2)\n\n\t\t\tleases[0] = *lease.DeepCopy()\n\t\t\tleases[0].Name = \"shard-1\"\n\t\t\tleases[0].Spec.HolderIdentity = ptr.To(\"shard-1\")\n\n\t\t\tleases[1] = *lease.DeepCopy()\n\t\t\tleases[1].Name = \"shard-2\"\n\t\t\tleases[1].Spec.HolderIdentity = nil\n\t\t\tleases[1].Spec.LeaseDurationSeconds = ptr.To[int32](1)\n\t\t\tleases[1].Spec.AcquireTime = ptr.To(metav1.NewMicroTime(now))\n\t\t\tleases[1].Spec.RenewTime = ptr.To(metav1.NewMicroTime(now))\n\n\t\t\tExpect(ToShards(leases, now)).To(ConsistOf(\n\t\t\t\tgstruct.MatchAllFields(gstruct.Fields{\n\t\t\t\t\t\"ID\":    Equal(\"shard-1\"),\n\t\t\t\t\t\"State\": Equal(Ready),\n\t\t\t\t\t\"Times\": gstruct.MatchFields(gstruct.IgnoreExtras, gstruct.Fields{\n\t\t\t\t\t\t\"Expiration\": Equal(now.Add(8 * time.Second)),\n\t\t\t\t\t}),\n\t\t\t\t}),\n\t\t\t\tgstruct.MatchAllFields(gstruct.Fields{\n\t\t\t\t\t\"ID\":    Equal(\"shard-2\"),\n\t\t\t\t\t\"State\": Equal(Dead),\n\t\t\t\t\t\"Times\": gstruct.MatchFields(gstruct.IgnoreExtras, gstruct.Fields{\n\t\t\t\t\t\t\"ToOrphaned\": Equal(time.Second + time.Minute),\n\t\t\t\t\t}),\n\t\t\t\t}),\n\t\t\t))\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/sharding/leases/state.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage leases\n\nimport (\n\t\"time\"\n\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n)\n\n// ShardState represents a state of a single shard which determines whether it is available for assigning objects to it\n// or whether it is unhealthy.\ntype ShardState int\n\nconst (\n\t// Unknown is the ShardState if the Lease is not present or misses required fields.\n\tUnknown ShardState = iota\n\t// Orphaned is the ShardState if the Lease has been in state Dead for at least 1 minute.\n\tOrphaned\n\t// Dead is the ShardState if the Lease is Uncertain and was successfully acquired by the sharder or if it was actively\n\t// released by the shard.\n\tDead\n\t// Uncertain is the ShardState if the Lease has expired at least leaseDuration ago.\n\tUncertain\n\t// Expired is the ShardState if the Lease has expired less than leaseDuration ago.\n\tExpired\n\t// Ready is the ShardState if the Lease is held by the shard and has not expired.\n\tReady\n)\n\n// KnownShardStates is a list of all known shard states.\nvar KnownShardStates = []ShardState{Orphaned, Dead, Uncertain, Expired, Ready}\n\n// String returns a string representation of this ShardState.\nfunc (s ShardState) String() string {\n\tswitch s {\n\tcase Orphaned:\n\t\treturn \"orphaned\"\n\tcase Dead:\n\t\treturn \"dead\"\n\tcase Uncertain:\n\t\treturn \"uncertain\"\n\tcase Expired:\n\t\treturn \"expired\"\n\tcase Ready:\n\t\treturn \"ready\"\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n\n// StateFromString returns the ShardState matching the given string representation.\nfunc StateFromString(state string) ShardState {\n\tswitch state {\n\tcase \"orphaned\":\n\t\treturn Orphaned\n\tcase \"dead\":\n\t\treturn Dead\n\tcase \"uncertain\":\n\t\treturn Uncertain\n\tcase \"expired\":\n\t\treturn Expired\n\tcase \"ready\":\n\t\treturn Ready\n\tdefault:\n\t\treturn Unknown\n\t}\n}\n\n// IsAvailable returns true for shard states that should be considered for object assignment.\nfunc (s ShardState) IsAvailable() bool {\n\treturn s >= Uncertain\n}\n\n// ToState returns the ShardState of the given Lease.\nfunc ToState(lease *coordinationv1.Lease, now time.Time) ShardState {\n\treturn toState(lease, ToTimes(lease, now))\n}\n\nfunc toState(lease *coordinationv1.Lease, t Times) ShardState {\n\t// check if lease was released or acquired by sharder\n\tif holder := lease.Spec.HolderIdentity; holder == nil || *holder == \"\" || *holder != lease.Name {\n\t\tif t.ToOrphaned <= 0 {\n\t\t\treturn Orphaned\n\t\t}\n\t\treturn Dead\n\t}\n\n\tswitch {\n\tcase t.ToUncertain <= 0:\n\t\treturn Uncertain\n\tcase t.ToExpired <= 0:\n\t\treturn Expired\n\t}\n\n\treturn Ready\n}\n"
  },
  {
    "path": "pkg/sharding/leases/state_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage leases_test\n\nimport (\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/ptr\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n)\n\nvar _ = Describe(\"ShardState\", func() {\n\tDescribe(\"#String\", func() {\n\t\tIt(\"should return the state as a string\", func() {\n\t\t\tExpect(Unknown.String()).To(Equal(\"unknown\"))\n\t\t\tExpect(Orphaned.String()).To(Equal(\"orphaned\"))\n\t\t\tExpect(Dead.String()).To(Equal(\"dead\"))\n\t\t\tExpect(Uncertain.String()).To(Equal(\"uncertain\"))\n\t\t\tExpect(Expired.String()).To(Equal(\"expired\"))\n\t\t\tExpect(Ready.String()).To(Equal(\"ready\"))\n\t\t\tExpect(ShardState(-1).String()).To(Equal(\"unknown\"))\n\t\t})\n\t})\n\n\tDescribe(\"#StateFromString\", func() {\n\t\tIt(\"should return the correct state matching the string\", func() {\n\t\t\tExpect(StateFromString(\"unknown\")).To(Equal(Unknown))\n\t\t\tExpect(StateFromString(\"orphaned\")).To(Equal(Orphaned))\n\t\t\tExpect(StateFromString(\"dead\")).To(Equal(Dead))\n\t\t\tExpect(StateFromString(\"uncertain\")).To(Equal(Uncertain))\n\t\t\tExpect(StateFromString(\"expired\")).To(Equal(Expired))\n\t\t\tExpect(StateFromString(\"ready\")).To(Equal(Ready))\n\t\t\tExpect(StateFromString(\"foo\")).To(Equal(Unknown))\n\t\t})\n\t})\n\n\tDescribe(\"#IsAvailable\", func() {\n\t\tIt(\"should return false for unavailable states\", func() {\n\t\t\tExpect(Unknown.IsAvailable()).To(BeFalse())\n\t\t\tExpect(Orphaned.IsAvailable()).To(BeFalse())\n\t\t\tExpect(Dead.IsAvailable()).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should return true for available states\", func() {\n\t\t\tExpect(Uncertain.IsAvailable()).To(BeTrue())\n\t\t\tExpect(Expired.IsAvailable()).To(BeTrue())\n\t\t\tExpect(Ready.IsAvailable()).To(BeTrue())\n\t\t})\n\t})\n\n\tDescribe(\"#ToState\", func() {\n\t\tvar (\n\t\t\tnow   time.Time\n\t\t\tlease *coordinationv1.Lease\n\t\t)\n\n\t\tBeforeEach(func() {\n\t\t\tnow = time.Now()\n\n\t\t\tlease = &coordinationv1.Lease{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName: \"shard\",\n\t\t\t\t},\n\t\t\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\t\t\tHolderIdentity:       ptr.To(\"shard\"),\n\t\t\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(now.Add(-2 * time.Minute))),\n\t\t\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(now.Add(-2 * time.Second))),\n\t\t\t\t},\n\t\t\t}\n\t\t})\n\n\t\tIt(\"should return ready if lease has not expired\", func() {\n\t\t\tExpect(ToState(lease, now)).To(Equal(Ready))\n\t\t})\n\n\t\tIt(\"should return expired if lease has expired\", func() {\n\t\t\tlease.Spec.RenewTime = ptr.To(metav1.NewMicroTime(now.Add(-15 * time.Second)))\n\t\t\tExpect(ToState(lease, now)).To(Equal(Expired))\n\t\t})\n\n\t\tIt(\"should return expired if acquireTime is missing\", func() {\n\t\t\tlease.Spec.AcquireTime = nil\n\t\t\tExpect(ToState(lease, now)).To(Equal(Expired))\n\t\t})\n\n\t\tIt(\"should return expired if renewTime is missing\", func() {\n\t\t\tlease.Spec.RenewTime = nil\n\t\t\tExpect(ToState(lease, now)).To(Equal(Expired))\n\t\t})\n\n\t\tIt(\"should return expired if leaseDuration is missing\", func() {\n\t\t\tlease.Spec.LeaseDurationSeconds = nil\n\t\t\tExpect(ToState(lease, now)).To(Equal(Expired))\n\t\t})\n\n\t\tIt(\"should return uncertain if lease has expired more than leaseDuration ago\", func() {\n\t\t\tlease.Spec.RenewTime = ptr.To(metav1.NewMicroTime(now.Add(-25 * time.Second)))\n\t\t\tExpect(ToState(lease, now)).To(Equal(Uncertain))\n\t\t})\n\n\t\tIt(\"should return dead if lease has been released\", func() {\n\t\t\tlease.Spec.HolderIdentity = nil\n\t\t\tExpect(ToState(lease, now)).To(Equal(Dead))\n\n\t\t\tlease.Spec.HolderIdentity = ptr.To(\"\")\n\t\t\tExpect(ToState(lease, now)).To(Equal(Dead))\n\t\t})\n\n\t\tIt(\"should return dead if lease has been acquired by sharder\", func() {\n\t\t\tlease.Spec.HolderIdentity = ptr.To(\"shardlease-controller\")\n\t\t\tlease.Spec.LeaseDurationSeconds = ptr.To[int32](20)\n\t\t\tlease.Spec.AcquireTime = ptr.To(metav1.NewMicroTime(now))\n\t\t\tlease.Spec.RenewTime = ptr.To(metav1.NewMicroTime(now))\n\t\t\tExpect(ToState(lease, now)).To(Equal(Dead))\n\t\t})\n\n\t\tIt(\"should return orphaned if lease has been released 1 minute and leaseDuration ago\", func() {\n\t\t\tlease.Spec.HolderIdentity = nil\n\t\t\tlease.Spec.LeaseDurationSeconds = ptr.To[int32](1)\n\t\t\tlease.Spec.AcquireTime = ptr.To(metav1.NewMicroTime(now.Add(-time.Minute - time.Second)))\n\t\t\tlease.Spec.RenewTime = ptr.To(metav1.NewMicroTime(now.Add(-time.Minute - time.Second)))\n\t\t\tExpect(ToState(lease, now)).To(Equal(Orphaned))\n\t\t})\n\n\t\tIt(\"should return orphaned if lease has been acquired by sharder 1 minute and ago\", func() {\n\t\t\tlease.Spec.HolderIdentity = ptr.To(\"shardlease-controller\")\n\t\t\tlease.Spec.LeaseDurationSeconds = ptr.To[int32](20)\n\t\t\tlease.Spec.AcquireTime = ptr.To(metav1.NewMicroTime(now.Add(-time.Minute - 20*time.Second)))\n\t\t\tlease.Spec.RenewTime = ptr.To(metav1.NewMicroTime(now.Add(-time.Minute - 20*time.Second)))\n\t\t\tExpect(ToState(lease, now)).To(Equal(Orphaned))\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/sharding/leases/times.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage leases\n\nimport (\n\t\"time\"\n\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n)\n\nconst (\n\tdefaultLeaseDuration = 15 * time.Second\n\tleaseTTL             = time.Minute\n)\n\n// Times holds the parsed times and durations of the Lease object.\ntype Times struct {\n\t// Expiration is the time when the Lease expires (RenewTime + LeaseDurationSeconds)\n\tExpiration time.Time\n\t// LeaseDuration is LeaseDurationSeconds represented as a Duration.\n\tLeaseDuration time.Duration\n\n\t// ToExpired is the duration until the Lease expires (Expiration - now).\n\tToExpired time.Duration\n\t// ToUncertain is the duration until the Shard Lease becomes uncertain and should get acquired by the sharder\n\t// (ToExpired + LeaseDuration).\n\tToUncertain time.Duration\n\t// ToOrphaned is the duration until the Lease becomes orphaned and should get cleaned up (ToExpired + leaseTTL).\n\tToOrphaned time.Duration\n}\n\n// ToTimes parses the times and durations in the given Lease object and returns them in the Times representation.\nfunc ToTimes(lease *coordinationv1.Lease, now time.Time) Times {\n\tvar (\n\t\tt               = Times{}\n\t\tacquireTime     = lease.Spec.AcquireTime\n\t\trenewTime       = lease.Spec.RenewTime\n\t\tdurationSeconds = lease.Spec.LeaseDurationSeconds\n\t)\n\n\tif acquireTime == nil || renewTime == nil || durationSeconds == nil {\n\t\tt.Expiration = now\n\t\tt.LeaseDuration = defaultLeaseDuration\n\t} else {\n\t\tt.LeaseDuration = time.Duration(*durationSeconds) * time.Second\n\t\tt.Expiration = renewTime.Add(t.LeaseDuration)\n\t}\n\n\tt.ToExpired = t.Expiration.Sub(now)\n\tt.ToUncertain = t.ToExpired + t.LeaseDuration\n\t// ToOrphaned only applies, if lease is released or acquired by sharder\n\tt.ToOrphaned = t.ToExpired + leaseTTL\n\n\treturn t\n}\n"
  },
  {
    "path": "pkg/sharding/leases/times_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage leases_test\n\nimport (\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/ptr\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n)\n\nvar _ = Describe(\"Times\", func() {\n\tDescribe(\"#ToTimes\", func() {\n\t\tvar (\n\t\t\tnow   time.Time\n\t\t\tlease *coordinationv1.Lease\n\t\t)\n\n\t\tBeforeEach(func() {\n\t\t\tnow = time.Now()\n\n\t\t\tlease = &coordinationv1.Lease{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName: \"shard\",\n\t\t\t\t},\n\t\t\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\t\t\tHolderIdentity:       ptr.To(\"shard\"),\n\t\t\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(now.Add(-2 * time.Minute))),\n\t\t\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(now.Add(-2 * time.Second))),\n\t\t\t\t},\n\t\t\t}\n\t\t})\n\n\t\tIt(\"should return the correct times for a ready shard\", func() {\n\t\t\tmatchTimes(ToTimes(lease, now), Times{\n\t\t\t\tExpiration:    now.Add(8 * time.Second),\n\t\t\t\tLeaseDuration: 10 * time.Second,\n\t\t\t\tToExpired:     8 * time.Second,\n\t\t\t\tToUncertain:   18 * time.Second,\n\t\t\t\tToOrphaned:    8*time.Second + time.Minute,\n\t\t\t})\n\t\t})\n\n\t\tIt(\"should return the correct times for a lease acquired by the sharder\", func() {\n\t\t\tlease.Spec.HolderIdentity = ptr.To(\"shardlease-controller\")\n\t\t\tlease.Spec.LeaseDurationSeconds = ptr.To[int32](20)\n\t\t\tlease.Spec.AcquireTime = ptr.To(metav1.NewMicroTime(now.Add(-2 * time.Second)))\n\t\t\tlease.Spec.RenewTime = ptr.To(metav1.NewMicroTime(now.Add(-2 * time.Second)))\n\n\t\t\tmatchTimes(ToTimes(lease, now), Times{\n\t\t\t\tExpiration:    now.Add(18 * time.Second),\n\t\t\t\tLeaseDuration: 20 * time.Second,\n\t\t\t\tToExpired:     18 * time.Second,\n\t\t\t\tToUncertain:   38 * time.Second,\n\t\t\t\tToOrphaned:    18*time.Second + time.Minute,\n\t\t\t})\n\t\t})\n\n\t\tIt(\"should return the correct times for a released lease\", func() {\n\t\t\tlease.Spec.HolderIdentity = nil\n\t\t\tlease.Spec.LeaseDurationSeconds = ptr.To[int32](1)\n\t\t\tlease.Spec.AcquireTime = ptr.To(metav1.NewMicroTime(now))\n\t\t\tlease.Spec.RenewTime = ptr.To(metav1.NewMicroTime(now))\n\n\t\t\tmatchTimes(ToTimes(lease, now), Times{\n\t\t\t\tExpiration:    now.Add(time.Second),\n\t\t\t\tLeaseDuration: time.Second,\n\t\t\t\tToExpired:     time.Second,\n\t\t\t\tToUncertain:   2 * time.Second,\n\t\t\t\tToOrphaned:    time.Second + time.Minute,\n\t\t\t})\n\t\t})\n\n\t\tIt(\"should set expiration to now if some field is missing\", func() {\n\t\t\texpectedTimes := Times{\n\t\t\t\tExpiration:    now,\n\t\t\t\tLeaseDuration: 15 * time.Second,\n\t\t\t\tToExpired:     0,\n\t\t\t\tToUncertain:   15 * time.Second,\n\t\t\t\tToOrphaned:    time.Minute,\n\t\t\t}\n\n\t\t\tbrokenLease := lease.DeepCopy()\n\t\t\tbrokenLease.Spec.AcquireTime = nil\n\t\t\tmatchTimes(ToTimes(brokenLease, now), expectedTimes)\n\n\t\t\tbrokenLease = lease.DeepCopy()\n\t\t\tbrokenLease.Spec.RenewTime = nil\n\t\t\tmatchTimes(ToTimes(brokenLease, now), expectedTimes)\n\n\t\t\tbrokenLease = lease.DeepCopy()\n\t\t\tbrokenLease.Spec.LeaseDurationSeconds = nil\n\t\t\tmatchTimes(ToTimes(brokenLease, now), expectedTimes)\n\t\t})\n\t})\n})\n\nfunc matchTimes(actual, expected Times) {\n\tGinkgoHelper()\n\n\tExpect(actual.Expiration.String()).To(Equal(expected.Expiration.String()), \"should match expected Expiration time\")\n\tExpect(actual.LeaseDuration.String()).To(Equal(expected.LeaseDuration.String()), \"should match expected LeaseDuration duration\")\n\tExpect(actual.ToExpired.String()).To(Equal(expected.ToExpired.String()), \"should match expected ToExpired duration\")\n\tExpect(actual.ToUncertain.String()).To(Equal(expected.ToUncertain.String()), \"should match expected ToUncertain duration\")\n\tExpect(actual.ToOrphaned.String()).To(Equal(expected.ToOrphaned.String()), \"should match expected ToOrphaned duration\")\n}\n"
  },
  {
    "path": "pkg/sharding/predicate/controllerring.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage predicate\n\nimport (\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n)\n\n// ControllerRingCreatedOrUpdated reacts on create and update events with generation changes but ignores delete\n// events. On deletion, there is nothing to do for the sharding controllers.\nfunc ControllerRingCreatedOrUpdated() predicate.Predicate {\n\treturn predicate.And(\n\t\tpredicate.GenerationChangedPredicate{},\n\t\t// ignore deletion of ControllerRings\n\t\tpredicate.Funcs{\n\t\t\tCreateFunc: func(_ event.CreateEvent) bool { return true },\n\t\t\tUpdateFunc: func(_ event.UpdateEvent) bool { return true },\n\t\t\tDeleteFunc: func(_ event.DeleteEvent) bool { return false },\n\t\t},\n\t)\n}\n"
  },
  {
    "path": "pkg/sharding/predicate/controllerring_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage predicate_test\n\nimport (\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/predicate\"\n)\n\nvar _ = Describe(\"ControllerRing\", func() {\n\tvar (\n\t\tp predicate.Predicate\n\n\t\tobj, objOld *shardingv1alpha1.ControllerRing\n\t)\n\n\tBeforeEach(func() {\n\t\tobj = &shardingv1alpha1.ControllerRing{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tGeneration: 1,\n\t\t\t},\n\t\t}\n\t\tobjOld = obj.DeepCopy()\n\t})\n\n\tDescribe(\"#ControllerRingCreatedOrUpdated\", func() {\n\t\tBeforeEach(func() {\n\t\t\tp = ControllerRingCreatedOrUpdated()\n\t\t})\n\n\t\tIt(\"should react on create events\", func() {\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should react on spec updates\", func() {\n\t\t\tobj.Generation++\n\t\t\tobj.Spec.Resources = append(obj.Spec.Resources, shardingv1alpha1.RingResource{\n\t\t\t\tGroupResource: metav1.GroupResource{Resource: \"pods\"},\n\t\t\t})\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should ignore status updates\", func() {\n\t\t\tobj.Status.AvailableShards++\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should ignore delete events\", func() {\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeFalse())\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/sharding/predicate/lease.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage predicate\n\nimport (\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\t\"k8s.io/utils/clock\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n)\n\n// IsShardLease filters for events on Lease objects that have a non-empty label specifying the ControllerRing.\nfunc IsShardLease() predicate.Predicate {\n\treturn predicate.NewPredicateFuncs(func(obj client.Object) bool {\n\t\tlease, ok := obj.(*coordinationv1.Lease)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\n\t\treturn lease.Labels[shardingv1alpha1.LabelControllerRing] != \"\"\n\t})\n}\n\n// ShardLeaseStateChanged reacts on lease events where the shard's state changes.\nfunc ShardLeaseStateChanged(clock clock.PassiveClock) predicate.Predicate {\n\treturn predicate.Funcs{\n\t\tUpdateFunc: func(e event.UpdateEvent) bool {\n\t\t\toldLease, ok := e.ObjectOld.(*coordinationv1.Lease)\n\t\t\tif !ok {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tnewLease, ok := e.ObjectNew.(*coordinationv1.Lease)\n\t\t\tif !ok {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\t// only react if the shard's state changed\n\t\t\tnow := clock.Now()\n\t\t\treturn leases.ToState(oldLease, now) != leases.ToState(newLease, now)\n\t\t},\n\t}\n}\n\n// ShardLeaseAvailabilityChanged reacts on lease events where the shard's availability changes.\nfunc ShardLeaseAvailabilityChanged(clock clock.PassiveClock) predicate.Predicate {\n\treturn predicate.Funcs{\n\t\tCreateFunc: func(e event.CreateEvent) bool {\n\t\t\tlease, ok := e.Object.(*coordinationv1.Lease)\n\t\t\tif !ok {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\t// only react if the new shard is available right away\n\t\t\treturn leases.ToState(lease, clock.Now()).IsAvailable()\n\t\t},\n\t\tUpdateFunc: func(e event.UpdateEvent) bool {\n\t\t\toldLease, ok := e.ObjectOld.(*coordinationv1.Lease)\n\t\t\tif !ok {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tnewLease, ok := e.ObjectNew.(*coordinationv1.Lease)\n\t\t\tif !ok {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\t// only react if the shard's availability changed\n\t\t\tnow := clock.Now()\n\t\t\treturn leases.ToState(oldLease, now).IsAvailable() != leases.ToState(newLease, now).IsAvailable()\n\t\t},\n\t\tDeleteFunc: func(e event.DeleteEvent) bool {\n\t\t\tlease, ok := e.Object.(*coordinationv1.Lease)\n\t\t\tif !ok {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tif e.DeleteStateUnknown {\n\t\t\t\t// If we missed the delete event, we cannot know the final state of the shard (available or not) for sure.\n\t\t\t\t// The included object might be stale, as we might have missed a relevant update before as well.\n\t\t\t\t// In this case, react for safety.\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\t// only react if the removed shard was still available\n\t\t\treturn leases.ToState(lease, clock.Now()).IsAvailable()\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "pkg/sharding/predicate/lease_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage predicate_test\n\nimport (\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/clock/testing\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/predicate\"\n)\n\nvar _ = Describe(\"Lease\", func() {\n\tvar (\n\t\tp predicate.Predicate\n\n\t\tfakeClock   *testing.FakePassiveClock\n\t\tobj, objOld *coordinationv1.Lease\n\t)\n\n\tBeforeEach(func() {\n\t\tfakeClock = testing.NewFakePassiveClock(time.Now())\n\n\t\tobj = &coordinationv1.Lease{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tName: \"foo-0\",\n\t\t\t},\n\t\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\t\tHolderIdentity:       ptr.To(\"foo-0\"),\n\t\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-5 * time.Minute))),\n\t\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-2 * time.Second))),\n\t\t\t},\n\t\t}\n\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"alpha.sharding.timebertt.dev/controllerring\", \"foo\")\n\t\tobjOld = obj.DeepCopy()\n\t})\n\n\tDescribe(\"#IsShardLease\", func() {\n\t\tBeforeEach(func() {\n\t\t\tp = IsShardLease()\n\t\t})\n\n\t\tIt(\"should ignore other object kinds\", func() {\n\t\t\tpod := &corev1.Pod{}\n\n\t\t\tExpect(p.Create(event.CreateEvent{Object: pod})).To(BeFalse())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: pod, ObjectNew: pod})).To(BeFalse())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: pod})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should ignore leases without label\", func() {\n\t\t\tdelete(obj.Labels, \"alpha.sharding.timebertt.dev/controllerring\")\n\t\t\tobjOld = obj.DeepCopy()\n\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeFalse())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should ignore leases with empty label\", func() {\n\t\t\tmetav1.SetMetaDataLabel(&obj.ObjectMeta, \"alpha.sharding.timebertt.dev/controllerring\", \"\")\n\t\t\tobjOld = obj.DeepCopy()\n\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeFalse())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should react on lease events with label\", func() {\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeTrue())\n\t\t})\n\t})\n\n\tDescribe(\"#ShardLeaseStateChanged\", func() {\n\t\tBeforeEach(func() {\n\t\t\tp = ShardLeaseStateChanged(fakeClock)\n\t\t})\n\n\t\tIt(\"should react on all create events\", func() {\n\t\t\tExpect(p.Create(event.CreateEvent{})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should react on all delete events\", func() {\n\t\t\tExpect(p.Delete(event.DeleteEvent{})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should ignore other object kinds on update events\", func() {\n\t\t\tpod := &corev1.Pod{}\n\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: pod, ObjectNew: pod})).To(BeFalse())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: pod})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should react when shard state changed to dead (lease released)\", func() {\n\t\t\tobj.Spec.HolderIdentity = nil\n\n\t\t\tExpect(leases.ToState(objOld, fakeClock.Now())).To(Equal(leases.Ready))\n\t\t\tExpect(leases.ToState(obj, fakeClock.Now())).To(Equal(leases.Dead))\n\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should react when shard state changed to ready (renewed after expired)\", func() {\n\t\t\tobjOld.Spec.RenewTime = ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-time.Duration(*obj.Spec.LeaseDurationSeconds+1) * time.Second)))\n\n\t\t\tExpect(leases.ToState(objOld, fakeClock.Now())).To(Equal(leases.Expired))\n\t\t\tExpect(leases.ToState(obj, fakeClock.Now())).To(Equal(leases.Ready))\n\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should ignore when shard state hasn't changed\", func() {\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\n\t\t\tobj.Spec.HolderIdentity = nil\n\t\t\tobjOld.Spec.HolderIdentity = nil\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\t\t})\n\t})\n\n\tDescribe(\"#ShardLeaseAvailabilityChanged\", func() {\n\t\tBeforeEach(func() {\n\t\t\tp = ShardLeaseAvailabilityChanged(fakeClock)\n\t\t})\n\n\t\tIt(\"should react on create events if shard is available\", func() {\n\t\t\tExpect(leases.ToState(obj, fakeClock.Now())).To(Equal(leases.Ready))\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should ignore create events if shard is not available\", func() {\n\t\t\tobj.Spec.HolderIdentity = nil\n\t\t\tExpect(leases.ToState(obj, fakeClock.Now())).To(Equal(leases.Dead))\n\t\t\tExpect(p.Create(event.CreateEvent{Object: obj})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should react on delete events if shard was available\", func() {\n\t\t\tExpect(leases.ToState(obj, fakeClock.Now())).To(Equal(leases.Ready))\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should ignore delete events if shard was not available\", func() {\n\t\t\tobj.Spec.HolderIdentity = nil\n\t\t\tExpect(leases.ToState(obj, fakeClock.Now())).To(Equal(leases.Dead))\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should ignore other object kinds\", func() {\n\t\t\tpod := &corev1.Pod{}\n\n\t\t\tExpect(p.Create(event.CreateEvent{Object: pod})).To(BeFalse())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: pod, ObjectNew: pod})).To(BeFalse())\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: pod})).To(BeFalse())\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: pod})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should react when shard state changed to dead (lease released)\", func() {\n\t\t\tobj.Spec.HolderIdentity = nil\n\n\t\t\tExpect(leases.ToState(objOld, fakeClock.Now())).To(Equal(leases.Ready))\n\t\t\tExpect(leases.ToState(obj, fakeClock.Now())).To(Equal(leases.Dead))\n\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should ignore when shard state changed to ready (renewed after expired)\", func() {\n\t\t\tobjOld.Spec.RenewTime = ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-time.Duration(*obj.Spec.LeaseDurationSeconds+1) * time.Second)))\n\n\t\t\tExpect(leases.ToState(objOld, fakeClock.Now())).To(Equal(leases.Expired))\n\t\t\tExpect(leases.ToState(obj, fakeClock.Now())).To(Equal(leases.Ready))\n\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should react when shard state changed to ready (renewed after dead)\", func() {\n\t\t\tobjOld.Spec.HolderIdentity = nil\n\n\t\t\tExpect(leases.ToState(objOld, fakeClock.Now())).To(Equal(leases.Dead))\n\t\t\tExpect(leases.ToState(obj, fakeClock.Now())).To(Equal(leases.Ready))\n\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeTrue())\n\t\t})\n\n\t\tIt(\"should ignore when shard state hasn't changed\", func() {\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\n\t\t\tobj.Spec.HolderIdentity = nil\n\t\t\tobjOld.Spec.HolderIdentity = nil\n\t\t\tExpect(p.Update(event.UpdateEvent{ObjectOld: objOld, ObjectNew: obj})).To(BeFalse())\n\t\t})\n\n\t\tIt(\"should react if final delete state is unknown even if lease was unavailable\", func() {\n\t\t\tobj.Spec.HolderIdentity = nil\n\n\t\t\tExpect(p.Delete(event.DeleteEvent{Object: obj, DeleteStateUnknown: true})).To(BeTrue())\n\t\t})\n\t})\n})\n"
  },
  {
    "path": "pkg/sharding/predicate/predicate_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage predicate_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestPredicate(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Sharding Predicates Suite\")\n}\n"
  },
  {
    "path": "pkg/sharding/ring/ring.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage ring\n\nimport (\n\t\"time\"\n\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\tshardingmetrics \"github.com/timebertt/kubernetes-controller-sharding/pkg/metrics\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/consistenthash\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n)\n\n// FromLeases creates a ring from the given membership information (shard leases). It transforms shard leases into a\n// usable form, i.e., a hash ring and leases.Shards.\n// This is a central function in the sharding implementation bringing together the leases package with the\n// consistenthash package.\n// In short, it determines the subset of available shards and constructs a new consistenthash.Ring with it.\nfunc FromLeases(controllerRing *shardingv1alpha1.ControllerRing, leaseList *coordinationv1.LeaseList, now time.Time) (*consistenthash.Ring, leases.Shards) {\n\t// determine ready shards and calculate hash ring\n\tshards := leases.ToShards(leaseList.Items, now)\n\tavailableShards := shards.AvailableShards().IDs()\n\tring := consistenthash.New(nil, 0, availableShards...)\n\n\tshardingmetrics.RingCalculationsTotal.WithLabelValues(controllerRing.Name).Inc()\n\n\treturn ring, shards\n}\n"
  },
  {
    "path": "pkg/sharding/ring/ring_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage ring_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestRing(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Sharding Ring Suite\")\n}\n"
  },
  {
    "path": "pkg/sharding/ring/ring_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage ring_test\n\nimport (\n\t\"strconv\"\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"k8s.io/utils/ptr\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/consistenthash\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/ring\"\n)\n\nvar _ = Describe(\"FromLeases\", func() {\n\tvar (\n\t\tnow            time.Time\n\t\tcontrollerRing *shardingv1alpha1.ControllerRing\n\t\tleaseList      *coordinationv1.LeaseList\n\t)\n\n\tBeforeEach(func() {\n\t\tnow = time.Now()\n\t\tcontrollerRing = &shardingv1alpha1.ControllerRing{ObjectMeta: metav1.ObjectMeta{Name: \"foo\"}}\n\n\t\tleaseList = &coordinationv1.LeaseList{}\n\n\t\tleaseTemplate := &coordinationv1.Lease{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tName: \"foo-0\",\n\t\t\t},\n\t\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\t\tHolderIdentity:       ptr.To(\"foo-0\"),\n\t\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(now.Add(-5 * time.Minute))),\n\t\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(now.Add(-2 * time.Second))),\n\t\t\t},\n\t\t}\n\n\t\tlease := leaseTemplate.DeepCopy()\n\t\tleaseList.Items = append(leaseList.Items, *lease)\n\n\t\tlease = leaseTemplate.DeepCopy()\n\t\tlease.Name = \"foo-1\"\n\t\tlease.Spec.HolderIdentity = ptr.To(\"foo-1\")\n\t\tleaseList.Items = append(leaseList.Items, *lease)\n\n\t\tlease = leaseTemplate.DeepCopy()\n\t\tlease.Name = \"foo-2\"\n\t\tlease.Spec.HolderIdentity = nil\n\t\tleaseList.Items = append(leaseList.Items, *lease)\n\n\t\tlease = leaseTemplate.DeepCopy()\n\t\tlease.Name = \"foo-3\"\n\t\tlease.Spec.RenewTime = ptr.To(metav1.NewMicroTime(now.Add(-time.Minute)))\n\t\tleaseList.Items = append(leaseList.Items, *lease)\n\t})\n\n\tIt(\"should create a ring from the available shards\", func() {\n\t\tring, shards := FromLeases(controllerRing, leaseList, now)\n\t\tExpect(ring).NotTo(BeNil())\n\t\tExpect(shards).To(HaveLen(4))\n\t\tExpect(shards.AvailableShards().IDs()).To(ConsistOf(\"foo-0\", \"foo-1\"))\n\t\tExpect(probeRingNodes(ring)).To(ConsistOf(\"foo-0\", \"foo-1\"))\n\t})\n})\n\nfunc probeRingNodes(ring *consistenthash.Ring) []string {\n\tnodes := sets.New[string]()\n\n\tfor i := 0; i < 1000; i++ {\n\t\tnodes.Insert(ring.Hash(strconv.Itoa(i)))\n\t}\n\n\treturn nodes.UnsortedList()\n}\n"
  },
  {
    "path": "pkg/utils/client/client_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage client_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestClient(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Client Utils Suite\")\n}\n"
  },
  {
    "path": "pkg/utils/client/options.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage client\n\nimport (\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n)\n\n// ResourceVersion is a client.GetOption and client.ListOption that sets the resourceVersion query parameter.\n// See https://kubernetes.io/docs/reference/using-api/api-concepts/#the-resourceversion-parameter\n// Note: this doesn't take effect if there's a later option that overwrites the Raw field (e.g. ListOptions with Raw\n// set).\ntype ResourceVersion string\n\nfunc (r ResourceVersion) ApplyToGet(opts *client.GetOptions) {\n\tif opts.Raw == nil {\n\t\topts.Raw = &metav1.GetOptions{}\n\t}\n\topts.Raw.ResourceVersion = string(r)\n}\n\nfunc (r ResourceVersion) ApplyToList(opts *client.ListOptions) {\n\tif opts.Raw == nil {\n\t\topts.Raw = &metav1.ListOptions{}\n\t}\n\topts.Raw.ResourceVersion = string(r)\n}\n"
  },
  {
    "path": "pkg/utils/client/options_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage client_test\n\nimport (\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/client\"\n)\n\nvar _ = Describe(\"ResourceVersion\", func() {\n\tIt(\"should set the resourceVersion on GetOptions\", func() {\n\t\topts := &client.GetOptions{}\n\t\topts.ApplyOptions([]client.GetOption{ResourceVersion(\"1\")})\n\n\t\tExpect(opts.Raw.ResourceVersion).To(Equal(\"1\"))\n\t})\n\n\tIt(\"should set the resourceVersion on ListOptions\", func() {\n\t\topts := &client.ListOptions{}\n\t\topts.ApplyOptions([]client.ListOption{ResourceVersion(\"1\")})\n\n\t\tExpect(opts.Raw.ResourceVersion).To(Equal(\"1\"))\n\t})\n})\n"
  },
  {
    "path": "pkg/utils/client/scheme.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage client\n\nimport (\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\tutilruntime \"k8s.io/apimachinery/pkg/util/runtime\"\n\tclientgoscheme \"k8s.io/client-go/kubernetes/scheme\"\n\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n)\n\n// SharderScheme is the scheme that the sharder uses.\nvar SharderScheme = runtime.NewScheme()\n\nfunc init() {\n\tschemeBuilder := runtime.NewSchemeBuilder(\n\t\tclientgoscheme.AddToScheme,\n\t\tshardingv1alpha1.AddToScheme,\n\t\tconfigv1alpha1.AddToScheme,\n\t)\n\tutilruntime.Must(schemeBuilder.AddToScheme(SharderScheme))\n}\n"
  },
  {
    "path": "pkg/utils/errors/errors_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage errors_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestErrors(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Errors Utils Suite\")\n}\n"
  },
  {
    "path": "pkg/utils/errors/multi.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage errors\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// FormatErrors is like multierror.ListFormatFunc without the noisy newlines and tabs.\n// It also simplifies the format for a single error.\nfunc FormatErrors(es []error) string {\n\tif len(es) == 1 {\n\t\treturn es[0].Error()\n\t}\n\n\terrs := make([]string, len(es))\n\tfor i, err := range es {\n\t\terrs[i] = err.Error()\n\t}\n\n\treturn fmt.Sprintf(\"%d errors occurred: %s\", len(es), strings.Join(errs, \", \"))\n}\n"
  },
  {
    "path": "pkg/utils/errors/multi_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage errors_test\n\nimport (\n\t\"fmt\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/errors\"\n)\n\nvar _ = Describe(\"FormatErrors\", func() {\n\tIt(\"should return the single error\", func() {\n\t\tExpect(FormatErrors([]error{fmt.Errorf(\"foo\")})).To(Equal(\"foo\"))\n\t})\n\n\tIt(\"should return the error count and comma separated error list\", func() {\n\t\tExpect(\n\t\t\tFormatErrors([]error{fmt.Errorf(\"foo\"), fmt.Errorf(\"bar\")}),\n\t\t).To(\n\t\t\tEqual(\"2 errors occurred: foo, bar\"),\n\t\t)\n\t})\n})\n"
  },
  {
    "path": "pkg/utils/healthz/cache.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage healthz\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"sigs.k8s.io/controller-runtime/pkg/healthz\"\n)\n\ntype cacheSyncWaiter interface {\n\tWaitForCacheSync(ctx context.Context) bool\n}\n\n// CacheSync returns a new healthz.Checker that will pass if all informers in the given cacheSyncWaiter have synced.\nfunc CacheSync(cacheSyncWaiter cacheSyncWaiter) healthz.Checker {\n\treturn func(_ *http.Request) error {\n\t\t// cache.Cache.WaitForCacheSync is racy for a closed context, so use context with 5ms timeout instead.\n\t\tctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond)\n\t\tdefer cancel()\n\n\t\tif !cacheSyncWaiter.WaitForCacheSync(ctx) {\n\t\t\treturn fmt.Errorf(\"informers have not synced yet\")\n\t\t}\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "pkg/utils/healthz/cache_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage healthz_test\n\nimport (\n\t\"context\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/healthz\"\n)\n\nvar _ = Describe(\"CacheSync\", func() {\n\tIt(\"should succeed if all informers sync\", func() {\n\t\tchecker := CacheSync(fakeSyncWaiter(true))\n\t\tExpect(checker(nil)).NotTo(HaveOccurred())\n\t})\n\tIt(\"should fail if informers don't sync\", func() {\n\t\tchecker := CacheSync(fakeSyncWaiter(false))\n\t\tExpect(checker(nil)).To(MatchError(ContainSubstring(\"not synced\")))\n\t})\n})\n\ntype fakeSyncWaiter bool\n\nfunc (f fakeSyncWaiter) WaitForCacheSync(_ context.Context) bool {\n\treturn bool(f)\n}\n"
  },
  {
    "path": "pkg/utils/healthz/healthz_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage healthz_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestHealthz(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Healthz Suite\")\n}\n"
  },
  {
    "path": "pkg/utils/pager/pager.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage pager\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"k8s.io/apimachinery/pkg/api/meta\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\tutilruntime \"k8s.io/apimachinery/pkg/util/runtime\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n)\n\nconst (\n\tdefaultPageSize       = 500\n\tdefaultPageBufferSize = 10\n)\n\n// lister is the subset of client.Reader that ListPager uses.\ntype lister interface {\n\tList(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error\n}\n\n// New creates a new pager from the provided reader using the default options.\nfunc New(reader lister) *ListPager {\n\treturn &ListPager{\n\t\tReader:         reader,\n\t\tPageSize:       defaultPageSize,\n\t\tPageBufferSize: defaultPageBufferSize,\n\t}\n}\n\n// ListPager assists client code in breaking large list queries into multiple smaller chunks of PageSize or smaller.\n// The pager does not alter any fields on the initial options list except Continue.\n// It is implemented like client-go's pager but uses a controller-runtime client,\n// see https://github.com/kubernetes/client-go/blob/release-1.28/tools/pager/pager.go.\n// Exception: this ListPager also fixes the `specifying resource version is not allowed when using continue` error\n// in EachListItem and EachListItemWithAlloc.\ntype ListPager struct {\n\tReader lister\n\n\t// PageSize is the maximum number of objects to retrieve in individual list calls.\n\t// If a client.Limit option is passed, the pager uses the option's value instead.\n\tPageSize int64\n\t// Number of pages to buffer in EachListItem and EachListItemWithAlloc.\n\tPageBufferSize int32\n}\n\n// EachListItem fetches runtime.Object items using this ListPager and invokes fn on each item. If\n// fn returns an error, processing stops and that error is returned. If fn does not return an error,\n// any error encountered while retrieving the list from the server is returned. If the context\n// cancels or times out, the context error is returned. Since the list is retrieved in paginated\n// chunks, an \"Expired\" error (metav1.StatusReasonExpired) may be returned if the pagination list\n// requests exceed the expiration limit of the apiserver being called.\n//\n// Items are retrieved in chunks from the server to reduce the impact on the server with up to\n// ListPager.PageBufferSize chunks buffered concurrently in the background.\n//\n// If items passed to fn are retained for different durations, and you want to avoid\n// retaining the whole slice returned by p.Reader.List as long as any item is referenced,\n// use EachListItemWithAlloc instead.\nfunc (p *ListPager) EachListItem(ctx context.Context, list client.ObjectList, fn func(obj client.Object) error, opts ...client.ListOption) error {\n\treturn p.eachListChunkBuffered(ctx, list, func(list client.ObjectList) error {\n\t\treturn meta.EachListItem(list, func(obj runtime.Object) error {\n\t\t\treturn fn(obj.(client.Object))\n\t\t})\n\t}, opts...)\n}\n\n// EachListItemWithAlloc works like EachListItem, but avoids retaining references to the items slice returned by p.Reader.List.\n// It does this by making a shallow copy of non-pointer items in the slice returned by p.Reader.List.\n//\n// If the items passed to fn are not retained, or are retained for the same duration, use EachListItem instead for memory efficiency.\nfunc (p *ListPager) EachListItemWithAlloc(ctx context.Context, list client.ObjectList, fn func(obj client.Object) error, opts ...client.ListOption) error {\n\treturn p.eachListChunkBuffered(ctx, list, func(list client.ObjectList) error {\n\t\treturn meta.EachListItemWithAlloc(list, func(obj runtime.Object) error {\n\t\t\treturn fn(obj.(client.Object))\n\t\t})\n\t}, opts...)\n}\n\n// eachListChunkBuffered fetches runtimeObject list chunks using this ListPager and invokes fn on\n// each list chunk.  If fn returns an error, processing stops and that error is returned. If fn does\n// not return an error, any error encountered while retrieving the list from the server is\n// returned. If the context cancels or times out, the context error is returned. Since the list is\n// retrieved in paginated chunks, an \"Expired\" error (metav1.StatusReasonExpired) may be returned if\n// the pagination list requests exceed the expiration limit of the apiserver being called.\n//\n// Up to ListPager.PageBufferSize chunks are buffered concurrently in the background.\nfunc (p *ListPager) eachListChunkBuffered(ctx context.Context, list client.ObjectList, fn func(list client.ObjectList) error, opts ...client.ListOption) error {\n\tif p.PageBufferSize < 0 {\n\t\treturn fmt.Errorf(\"ListPager.PageBufferSize must be >= 0, got %d\", p.PageBufferSize)\n\t}\n\n\t// Ensure background goroutine is stopped if this call exits before all list items are\n\t// processed. Cancellation error from this deferred cancel call is never returned to caller;\n\t// either the list result has already been sent to bgResultC or the fn error is returned and\n\t// the cancellation error is discarded.\n\tctx, cancel := context.WithCancel(ctx)\n\tdefer cancel()\n\n\tchunkC := make(chan client.ObjectList, p.PageBufferSize)\n\tbgResultC := make(chan error, 1)\n\tgo func() {\n\t\tdefer utilruntime.HandleCrash()\n\n\t\tvar err error\n\t\tdefer func() {\n\t\t\tclose(chunkC)\n\t\t\tbgResultC <- err\n\t\t}()\n\t\terr = p.eachListChunk(ctx, list, func(chunk client.ObjectList) error {\n\t\t\tselect {\n\t\t\tcase chunkC <- chunk: // buffer the chunk, this can block\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn ctx.Err()\n\t\t\t}\n\t\t\treturn nil\n\t\t}, opts...)\n\t}()\n\n\tfor o := range chunkC {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tdefault:\n\t\t}\n\t\terr := fn(o)\n\t\tif err != nil {\n\t\t\treturn err // any fn error should be returned immediately\n\t\t}\n\t}\n\t// promote the results of our background goroutine to the foreground\n\treturn <-bgResultC\n}\n\n// eachListChunk fetches runtimeObject list chunks using this ListPager and invokes fn on each list\n// chunk. If fn returns an error, processing stops and that error is returned. If fn does not return\n// an error, any error encountered while retrieving the list from the server is returned. If the\n// context cancels or times out, the context error is returned. Since the list is retrieved in\n// paginated chunks, an \"Expired\" error (metav1.StatusReasonExpired) may be returned if the\n// pagination list requests exceed the expiration limit of the apiserver being called.\nfunc (p *ListPager) eachListChunk(ctx context.Context, list client.ObjectList, fn func(list client.ObjectList) error, opts ...client.ListOption) error {\n\toptions := &client.ListOptions{}\n\toptions.ApplyOptions(opts)\n\n\tif options.Limit == 0 {\n\t\toptions.Limit = p.PageSize\n\t}\n\tif options.Limit < 0 {\n\t\treturn fmt.Errorf(\"ListPager.PageSize must be >= 0, got %d\", options.Limit)\n\t}\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tdefault:\n\t\t}\n\n\t\t// create a new list to not share memory between paginated lists\n\t\tlist = list.DeepCopyObject().(client.ObjectList)\n\t\tif err := p.Reader.List(ctx, list, options); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif err := fn(list); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// if we have no more items, return.\n\t\tif len(list.GetContinue()) == 0 {\n\t\t\treturn nil\n\t\t}\n\n\t\t// set the next loop up\n\t\toptions.Continue = list.GetContinue()\n\t\t// Clear the ResourceVersion(Match) on the subsequent List calls to avoid the\n\t\t// `specifying resource version is not allowed when using continue` error.\n\t\t// See https://github.com/kubernetes/kubernetes/issues/85221#issuecomment-553748143.\n\t\tif options.Raw == nil {\n\t\t\toptions.Raw = &metav1.ListOptions{}\n\t\t}\n\t\toptions.Raw.ResourceVersion = \"\"\n\t\toptions.Raw.ResourceVersionMatch = \"\"\n\t}\n}\n"
  },
  {
    "path": "pkg/utils/pager/pager_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage pager_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestPager(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Pager Suite\")\n}\n"
  },
  {
    "path": "pkg/utils/pager/pager_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage pager_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tgomegatypes \"github.com/onsi/gomega/types\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/pager\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nvar _ = Describe(\"ListPager\", func() {\n\tconst (\n\t\tpageSize    = 2\n\t\tpageCount   = 5\n\t\tobjectCount = 9\n\t)\n\n\tvar (\n\t\tctx context.Context\n\n\t\tallPods []corev1.Pod\n\n\t\treader *lister\n\t\tpager  *ListPager\n\t)\n\n\tBeforeEach(func() {\n\t\tctx = context.Background()\n\n\t\tallPods = podSlice(0, objectCount)\n\n\t\treader = &lister{allPods: allPods}\n\n\t\tpager = New(reader)\n\t\tpager.PageSize = pageSize\n\t\tpager.PageBufferSize = 2\n\t})\n\n\tIt(\"should page all objects\", func() {\n\t\tvar pods []*corev1.Pod\n\n\t\tExpect(pager.EachListItem(ctx, &corev1.PodList{}, func(obj client.Object) error {\n\t\t\tpods = append(pods, obj.(*corev1.Pod))\n\t\t\treturn nil\n\t\t})).To(Succeed())\n\n\t\tExpect(pods).To(havePods(1, objectCount))\n\n\t\tExpect(reader.calls).To(Equal(pageCount))\n\t})\n\n\tIt(\"should page objects with the custom limit\", func() {\n\t\tvar pods []client.Object\n\n\t\ti := 0\n\t\tExpect(pager.EachListItem(ctx, &corev1.PodList{}, func(obj client.Object) error {\n\t\t\tif obj != &allPods[i] {\n\t\t\t\treturn fmt.Errorf(\"the pager should reuse the object\")\n\t\t\t}\n\t\t\ti++\n\t\t\tpods = append(pods, obj)\n\t\t\treturn nil\n\t\t}, client.Limit(objectCount+1))).To(Succeed())\n\n\t\tExpect(pods).To(havePods(1, objectCount))\n\n\t\tExpect(reader.calls).To(Equal(1))\n\t})\n\n\tIt(\"should fail due to negative page size\", func() {\n\t\tpager.PageSize = -1\n\t\tExpect(pager.EachListItem(ctx, &corev1.PodList{}, func(obj client.Object) error {\n\t\t\treturn nil\n\t\t})).To(MatchError(ContainSubstring(\"PageSize must be >= 0\")))\n\t})\n\n\tIt(\"should fail due to negative page buffer size\", func() {\n\t\tpager.PageBufferSize = -1\n\t\tExpect(pager.EachListItem(ctx, &corev1.PodList{}, func(obj client.Object) error {\n\t\t\treturn nil\n\t\t})).To(MatchError(ContainSubstring(\"PageBufferSize must be >= 0\")))\n\t})\n\n\tIt(\"should return the lister error\", func() {\n\t\tExpect(pager.EachListItem(ctx, &corev1.ConfigMapList{}, func(obj client.Object) error {\n\t\t\treturn nil\n\t\t})).To(MatchError(\"expected *corev1.PodList, got *v1.ConfigMapList\"))\n\t})\n\n\tIt(\"should return the iterator error\", func() {\n\t\tExpect(pager.EachListItem(ctx, &corev1.PodList{}, func(obj client.Object) error {\n\t\t\tif obj.GetName() == \"pod-5\" {\n\t\t\t\treturn fmt.Errorf(\"foo\")\n\t\t\t}\n\t\t\treturn nil\n\t\t})).To(MatchError(\"foo\"))\n\t})\n\n\tIt(\"should cancel the operation when the context is canceled\", func(specCtx SpecContext) {\n\t\tdone := make(chan struct{})\n\n\t\tblockConsumer := make(chan struct{})\n\t\tdefer close(blockConsumer)\n\n\t\tctx, cancel := context.WithCancel(specCtx)\n\t\tgo func() {\n\t\t\tdefer GinkgoRecover()\n\n\t\t\tExpect(pager.EachListItem(ctx, &corev1.PodList{}, func(obj client.Object) error {\n\t\t\t\t<-blockConsumer\n\t\t\t\treturn nil\n\t\t\t})).To(MatchError(context.Canceled))\n\n\t\t\tclose(done)\n\t\t}()\n\n\t\tcancel()\n\t\tEventually(specCtx, done).Should(BeClosed())\n\t}, SpecTimeout(time.Second))\n\n\tIt(\"should buffer the configured number of pages\", func(specCtx SpecContext) {\n\t\tdone := make(chan struct{})\n\n\t\tctx, cancel := context.WithCancel(specCtx)\n\t\tgo func() {\n\t\t\tdefer GinkgoRecover()\n\n\t\t\tExpect(pager.EachListItem(ctx, &corev1.PodList{}, func(obj client.Object) error {\n\t\t\t\t<-ctx.Done()\n\t\t\t\treturn nil\n\t\t\t})).To(MatchError(context.Canceled))\n\n\t\t\tclose(done)\n\t\t}()\n\n\t\t// consumer takes one chunk out and one chunk is produced but blocked,\n\t\t// so we have made PageBufferSize + 2 calls to the lister\n\t\tEventually(specCtx, reader.getCalls).Should(BeEquivalentTo(pager.PageBufferSize + 2))\n\n\t\tcancel()\n\t\tEventually(specCtx, done).Should(BeClosed())\n\t}, SpecTimeout(time.Second))\n\n\tIt(\"should correctly handle the resourceVersion fields\", func() {\n\t\tExpect(pager.EachListItem(ctx, &corev1.PodList{}, func(obj client.Object) error {\n\t\t\treturn nil\n\t\t}, &client.ListOptions{Raw: &metav1.ListOptions{\n\t\t\tResourceVersion:      \"0\",\n\t\t\tResourceVersionMatch: \"NotOlderThan\",\n\t\t}})).To(Succeed())\n\t})\n\n\tDescribe(\"#EachListItemWithAlloc\", func() {\n\t\tIt(\"should page all objects\", func() {\n\t\t\tvar pods []client.Object\n\n\t\t\ti := 0\n\t\t\tExpect(pager.EachListItemWithAlloc(ctx, &corev1.PodList{}, func(obj client.Object) error {\n\t\t\t\tif obj == &allPods[i] {\n\t\t\t\t\treturn fmt.Errorf(\"the pager should copy the object\")\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t\tpods = append(pods, obj)\n\t\t\t\treturn nil\n\t\t\t})).To(Succeed())\n\n\t\t\tExpect(pods).To(havePods(1, objectCount))\n\n\t\t\tExpect(reader.calls).To(Equal(pageCount))\n\t\t})\n\t})\n})\n\ntype lister struct {\n\tmu    sync.Mutex\n\tcalls int\n\n\tallPods      []corev1.Pod\n\tpreviousList client.ObjectList\n}\n\nfunc (l *lister) List(_ context.Context, list client.ObjectList, opts ...client.ListOption) error {\n\tfunc() {\n\t\tl.mu.Lock()\n\t\tdefer l.mu.Unlock()\n\t\tl.calls++\n\t}()\n\n\tif list == l.previousList {\n\t\treturn fmt.Errorf(\"the pager should not reuse the list for multiple calls\")\n\t}\n\tl.previousList = list\n\n\tpodList, ok := list.(*corev1.PodList)\n\tif !ok {\n\t\treturn fmt.Errorf(\"expected *corev1.PodList, got %T\", list)\n\t}\n\n\tlistOptions := &client.ListOptions{}\n\tlistOptions.ApplyOptions(opts)\n\n\tif l.calls > 1 {\n\t\tif listOptions.Raw.ResourceVersion != \"\" {\n\t\t\treturn fmt.Errorf(\"the pager should reset the resourceVersion field for consecutive calls\")\n\t\t}\n\t\tif listOptions.Raw.ResourceVersionMatch != \"\" {\n\t\t\treturn fmt.Errorf(\"the pager should reset the resourceVersionMatch field for consecutive calls\")\n\t\t}\n\t}\n\n\tlimit := listOptions.Limit\n\tif limit == 0 {\n\t\treturn fmt.Errorf(\"the pager should set limit\")\n\t}\n\n\tvar offset int64\n\tif listOptions.Continue != \"\" {\n\t\tvar err error\n\t\toffset, err = strconv.ParseInt(listOptions.Continue, 10, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tdefer func() {\n\t\tif offset+limit >= int64(len(l.allPods)) {\n\t\t\tpodList.Continue = \"\"\n\t\t} else {\n\t\t\tpodList.Continue = strconv.FormatInt(offset+int64(len(podList.Items)), 10)\n\t\t}\n\t}()\n\n\tpodList.Items = l.allPods[offset:min(int64(len(l.allPods)), offset+limit)]\n\treturn nil\n}\n\nfunc (l *lister) getCalls() int {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\treturn l.calls\n}\n\nfunc podSlice(offset, n int64) []corev1.Pod {\n\tpods := make([]corev1.Pod, n)\n\n\tfor i := int64(0); i < n; i++ {\n\t\tpods[i] = corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: \"pod-\" + strconv.FormatInt(offset+i+1, 10)}}\n\t}\n\n\treturn pods\n}\n\nfunc havePods(i, j int) gomegatypes.GomegaMatcher {\n\tvar matchers []any\n\n\tfor ; i <= j; i++ {\n\t\tmatchers = append(matchers, HaveName(\"pod-\"+strconv.Itoa(i)))\n\t}\n\n\treturn HaveExactElements(matchers...)\n}\n"
  },
  {
    "path": "pkg/utils/routes/profiling.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage routes\n\nimport (\n\t\"net/http\"\n\t\"net/http/pprof\"\n)\n\n// ProfilingHandlers is the set of profiling endpoints.\n// This can be added to controller-runtime's metrics server via manager.Options.Metrics.ExtraHandlers.\nvar ProfilingHandlers = map[string]http.Handler{\n\t\"/debug/pprof\":         http.RedirectHandler(\"/debug/pprof/\", http.StatusFound),\n\t\"/debug/pprof/\":        http.HandlerFunc(pprof.Index),\n\t\"/debug/pprof/profile\": http.HandlerFunc(pprof.Profile),\n\t\"/debug/pprof/symbol\":  http.HandlerFunc(pprof.Symbol),\n\t\"/debug/pprof/trace\":   http.HandlerFunc(pprof.Trace),\n}\n"
  },
  {
    "path": "pkg/utils/strings.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage utils\n\nimport (\n\t\"unicode\"\n)\n\n// CapitalizeFirst capitalizes the first letter in the given string.\nfunc CapitalizeFirst(in string) string {\n\tr := []rune(in)\n\tr[0] = unicode.ToUpper(r[0])\n\treturn string(r)\n}\n"
  },
  {
    "path": "pkg/utils/strings_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage utils_test\n\nimport (\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils\"\n)\n\nvar _ = Describe(\"CapitalizeFirst\", func() {\n\tIt(\"should capitalize the first letter\", func() {\n\t\tExpect(CapitalizeFirst(\"foo bar Baz\")).To(Equal(\"Foo bar Baz\"))\n\t\tExpect(CapitalizeFirst(\"Foo BAR Baz\")).To(Equal(\"Foo BAR Baz\"))\n\t\tExpect(CapitalizeFirst(\"FOO bar Baz\")).To(Equal(\"FOO bar Baz\"))\n\t})\n})\n"
  },
  {
    "path": "pkg/utils/test/envtest.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage test\n\nimport (\n\t\"os\"\n\t\"strings\"\n)\n\n// UseExistingCluster reads the `USE_EXISTING_CLUSTER` env var similar to what envtest does, though exported.\nfunc UseExistingCluster() bool {\n\treturn strings.ToLower(os.Getenv(\"USE_EXISTING_CLUSTER\")) == \"true\"\n}\n"
  },
  {
    "path": "pkg/utils/test/matchers/condition.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage matchers\n\nimport (\n\t. \"github.com/onsi/gomega\"\n\tgomegatypes \"github.com/onsi/gomega/types\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n)\n\n// MatchCondition is an alias for gomega.And to make matching conditions more readable, e.g.,\n//\n//\tExpect(controllerRing.Status.Conditions).To(ConsistOf(\n//\t\tMatchCondition(\n//\t\t\tOfType(shardingv1alpha1.ControllerRingReady),\n//\t\t\tWithStatus(metav1.ConditionTrue),\n//\t\t),\n//\t))\nvar MatchCondition = And\n\n// OfType returns a matcher for checking whether a condition has a certain type.\nfunc OfType(conditionType string) gomegatypes.GomegaMatcher {\n\treturn HaveField(\"Type\", Equal(conditionType))\n}\n\n// WithStatus returns a matcher for checking whether a condition has a certain status.\nfunc WithStatus(status metav1.ConditionStatus) gomegatypes.GomegaMatcher {\n\treturn HaveField(\"Status\", Equal(status))\n}\n\n// WithReason returns a matcher for checking whether a condition has a certain reason.\nfunc WithReason(reason string) gomegatypes.GomegaMatcher {\n\treturn HaveField(\"Reason\", Equal(reason))\n}\n\n// WithMessage returns a matcher for checking whether a condition has a certain message.\nfunc WithMessage(message string) gomegatypes.GomegaMatcher {\n\treturn HaveField(\"Message\", ContainSubstring(message))\n}\n"
  },
  {
    "path": "pkg/utils/test/matchers/errors.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage matchers\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/onsi/gomega/format\"\n)\n\ntype errorMatcher struct {\n\tmatch   func(error) bool\n\tmessage string\n}\n\nfunc (k *errorMatcher) Match(actual interface{}) (success bool, err error) {\n\tif actual == nil {\n\t\treturn false, nil\n\t}\n\n\tactualErr, actualOk := actual.(error)\n\tif !actualOk {\n\t\treturn false, fmt.Errorf(\"expected an error, got:\\n%s\", format.Object(actual, 1))\n\t}\n\n\treturn k.match(actualErr), nil\n}\n\nfunc (k *errorMatcher) FailureMessage(actual interface{}) (message string) {\n\treturn format.Message(actual, fmt.Sprintf(\"to be %s error\", k.message))\n}\nfunc (k *errorMatcher) NegatedFailureMessage(actual interface{}) (message string) {\n\treturn format.Message(actual, fmt.Sprintf(\"to not be %s error\", k.message))\n}\n"
  },
  {
    "path": "pkg/utils/test/matchers/matchers.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage matchers\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/onsi/gomega/gcustom\"\n\tgomegatypes \"github.com/onsi/gomega/types\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n)\n\n// BeNotFoundError checks if error is a NotFound error.\nfunc BeNotFoundError() gomegatypes.GomegaMatcher {\n\treturn &errorMatcher{\n\t\tmatch:   apierrors.IsNotFound,\n\t\tmessage: \"NotFound\",\n\t}\n}\n\n// BeFunc is a matcher that returns true if expected and actual are the same func.\nfunc BeFunc(expected any) gomegatypes.GomegaMatcher {\n\treturn gcustom.MakeMatcher(func(actual any) (bool, error) {\n\t\tvar (\n\t\t\tvalueExpected = reflect.ValueOf(expected)\n\t\t\tvalueActual   = reflect.ValueOf(actual)\n\t\t)\n\n\t\tif valueExpected.Kind() != reflect.Func {\n\t\t\treturn false, fmt.Errorf(\"expected should be a func, got %v\", valueExpected.Kind())\n\t\t}\n\t\tif valueActual.Kind() != reflect.Func {\n\t\t\treturn false, fmt.Errorf(\"actual should be a func, got %v\", valueActual.Kind())\n\t\t}\n\n\t\treturn valueExpected.Pointer() == valueActual.Pointer(), nil\n\t})\n}\n"
  },
  {
    "path": "pkg/utils/test/matchers/object.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage matchers\n\nimport (\n\t. \"github.com/onsi/gomega\"\n\tgomegatypes \"github.com/onsi/gomega/types\"\n)\n\n// HaveName succeeds if the actual object has a matching name.\nfunc HaveName(name string) gomegatypes.GomegaMatcher {\n\treturn HaveField(\"ObjectMeta.Name\", name)\n}\n\n// HaveNames succeeds if the actual list consists of matching names.\nfunc HaveNames(names ...string) gomegatypes.GomegaMatcher {\n\tmatchers := make([]any, len(names))\n\tfor i, n := range names {\n\t\tmatchers[i] = HaveName(n)\n\t}\n\n\treturn HaveField(\"Items\", ConsistOf(matchers...))\n}\n\n// HaveLabel succeeds if the actual object has a label with a matching key.\nfunc HaveLabel(key any) gomegatypes.GomegaMatcher {\n\treturn HaveField(\"ObjectMeta.Labels\", HaveKey(key))\n}\n\n// HaveLabelWithValue succeeds if the actual object has a label with a matching key and value.\nfunc HaveLabelWithValue(key, value any) gomegatypes.GomegaMatcher {\n\treturn HaveField(\"ObjectMeta.Labels\", HaveKeyWithValue(key, value))\n}\n"
  },
  {
    "path": "pkg/utils/test/object.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage test\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\n\t\"github.com/google/uuid\"\n)\n\n// RandomSuffix generates a random string that is safe to use as a name suffix in tests.\nfunc RandomSuffix() string {\n\tunique := uuid.New()\n\thash := sha256.Sum256(unique[:])\n\treturn hex.EncodeToString(hash[:])[:8]\n}\n"
  },
  {
    "path": "pkg/utils/test/paths.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage test\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\n\tutilruntime \"k8s.io/apimachinery/pkg/util/runtime\"\n)\n\n// RepoRoot returns a relative path from the current working directory to the repository root. For use in tests only.\nfunc RepoRoot() string {\n\trelativePath := \".\"\n\n\tdir, err := os.Getwd()\n\tutilruntime.Must(err)\n\n\tfor dir != \"/\" {\n\t\tif _, err := os.Stat(filepath.Join(dir, \"go.work\")); err == nil {\n\t\t\tbreak\n\t\t} else if !os.IsNotExist(err) {\n\t\t\tpanic(err)\n\t\t}\n\n\t\t// navigate one directory up, build up relative path\n\t\tdir = filepath.Dir(dir)\n\t\trelativePath = filepath.Join(relativePath, \"..\")\n\t}\n\n\treturn filepath.Clean(relativePath)\n}\n\n// PathShardingCRDs returns the path to the directory containing the sharding CRDs. For use in tests only.\nfunc PathShardingCRDs() string {\n\treturn filepath.Join(RepoRoot(), \"config\", \"crds\")\n}\n"
  },
  {
    "path": "pkg/utils/utils_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage utils_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestUtils(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Utils Suite\")\n}\n"
  },
  {
    "path": "pkg/webhook/add.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage webhook\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/webhook/sharder\"\n)\n\n// AddToManager adds all webhooks to the manager.\nfunc AddToManager(ctx context.Context, mgr manager.Manager, config *configv1alpha1.SharderConfig) error {\n\tif err := (&sharder.Handler{}).AddToManager(mgr); err != nil {\n\t\treturn fmt.Errorf(\"failed adding sharder webhook: %w\", err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/webhook/sharder/add.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"path\"\n\t\"strings\"\n\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/clock\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/webhook/admission\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n)\n\n// webhookPathPrefix is the path prefix at which the handler should be registered.\nconst webhookPathPrefix = \"/webhooks/sharder/controllerring/\"\n\n// AddToManager adds Handler to the given manager.\nfunc (h *Handler) AddToManager(mgr manager.Manager) error {\n\tif h.Reader == nil {\n\t\th.Reader = mgr.GetCache()\n\t}\n\tif h.Clock == nil {\n\t\th.Clock = clock.RealClock{}\n\t}\n\tif h.Metrics == nil {\n\t\th.Metrics = realMetrics{}\n\t}\n\n\tmgr.GetWebhookServer().Register(webhookPathPrefix, &admission.Webhook{\n\t\tHandler:         h,\n\t\tWithContextFunc: NewContextWithRequestPath,\n\t})\n\treturn nil\n}\n\n// WebhookPathForControllerRing returns the webhook handler path that should be used for implementing the given\n// ControllerRing. It is the reverse of ControllerRingForWebhookPath.\nfunc WebhookPathForControllerRing(ring *shardingv1alpha1.ControllerRing) string {\n\treturn path.Join(webhookPathPrefix, ring.Name)\n}\n\n// ControllerRingForWebhookPath returns the ControllerRing that is associated with the given webhook handler path.\n// It is the reverse of WebhookPathForControllerRing.\nfunc ControllerRingForWebhookPath(requestPath string) (*shardingv1alpha1.ControllerRing, error) {\n\tif !strings.HasPrefix(requestPath, webhookPathPrefix) {\n\t\treturn nil, fmt.Errorf(\"unexpected request path: %s\", requestPath)\n\t}\n\n\tname := strings.TrimPrefix(requestPath, webhookPathPrefix)\n\tif name == \"\" {\n\t\treturn nil, fmt.Errorf(\"unexpected request path: %s\", requestPath)\n\t}\n\n\treturn &shardingv1alpha1.ControllerRing{ObjectMeta: metav1.ObjectMeta{Name: name}}, nil\n}\n\ntype ctxKey int\n\n// keyRequestPath is used for storing the admission request's path in contexts.\nconst keyRequestPath ctxKey = 0\n\n// NewContextWithRequestPath augments the given context with the request's path.\nfunc NewContextWithRequestPath(ctx context.Context, r *http.Request) context.Context {\n\treturn context.WithValue(ctx, keyRequestPath, r.URL.Path)\n}\n\n// RequestPathFromContext returns the request's path stored in the given context.\nfunc RequestPathFromContext(ctx context.Context) (string, error) {\n\tif v, ok := ctx.Value(keyRequestPath).(string); ok {\n\t\treturn v, nil\n\t}\n\n\treturn \"\", fmt.Errorf(\"no request path found in context\")\n}\n"
  },
  {
    "path": "pkg/webhook/sharder/add_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder_test\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/webhook/sharder\"\n)\n\nvar _ = Describe(\"webhook path\", func() {\n\tconst controllerRingName = \"foo\"\n\n\tDescribe(\"#WebhookPathForControllerRing\", func() {\n\t\tIt(\"should return the correct webhook path\", func() {\n\t\t\tcontrollerRing := &shardingv1alpha1.ControllerRing{ObjectMeta: metav1.ObjectMeta{Name: controllerRingName}}\n\n\t\t\tExpect(WebhookPathForControllerRing(controllerRing)).To(Equal(\"/webhooks/sharder/controllerring/\" + controllerRingName))\n\t\t})\n\t})\n\n\tDescribe(\"#ControllerRingForWebhookPath\", func() {\n\t\tIt(\"should return an error for invalid paths\", func() {\n\t\t\tmatchError := MatchError(ContainSubstring(\"unexpected request path\"))\n\n\t\t\tExpect(ControllerRingForWebhookPath(\"/foo\")).Error().To(matchError)\n\t\t\tExpect(ControllerRingForWebhookPath(\"/webhooks\")).Error().To(matchError)\n\t\t\tExpect(ControllerRingForWebhookPath(\"/webhooks/sharder\")).Error().To(matchError)\n\t\t\tExpect(ControllerRingForWebhookPath(\"/webhooks/sharder/controllerring\")).Error().To(matchError)\n\t\t\tExpect(ControllerRingForWebhookPath(\"/webhooks/sharder/controllerring/\")).Error().To(matchError)\n\t\t})\n\n\t\tIt(\"should return a ControllerRing with name\", func() {\n\t\t\tExpect(ControllerRingForWebhookPath(\"/webhooks/sharder/controllerring/\" + controllerRingName)).To(\n\t\t\t\tEqual(&shardingv1alpha1.ControllerRing{\n\t\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: controllerRingName},\n\t\t\t\t}),\n\t\t\t)\n\t\t})\n\t})\n})\n\nvar _ = Describe(\"webhook context\", func() {\n\tIt(\"should inject and extract the request path into/from the context\", func() {\n\t\tconst path = \"/webhooks/sharder/controllerring/foo\"\n\n\t\tctx := NewContextWithRequestPath(context.Background(), &http.Request{\n\t\t\tURL: &url.URL{Path: path},\n\t\t})\n\n\t\tExpect(RequestPathFromContext(ctx)).To(Equal(path))\n\t})\n\n\tIt(\"should return an error if context doesn't contain path value\", func() {\n\t\tExpect(RequestPathFromContext(context.Background())).Error().To(MatchError(\"no request path found in context\"))\n\t})\n})\n"
  },
  {
    "path": "pkg/webhook/sharder/handler.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"gomodules.xyz/jsonpatch/v2\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/util/json\"\n\t\"k8s.io/utils/clock\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/webhook/admission\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/key\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/ring\"\n)\n\n// Handler handles admission requests and invalidates the static token in Secret resources related to ServiceAccounts.\ntype Handler struct {\n\tReader client.Reader\n\tClock  clock.PassiveClock\n\n\tMetrics Metrics\n}\n\nfunc (h *Handler) Handle(ctx context.Context, req admission.Request) admission.Response {\n\tlog := logf.FromContext(ctx)\n\n\tcontrollerRing, err := ControllerRingForRequest(ctx, h.Reader)\n\tif err != nil {\n\t\treturn admission.Errored(http.StatusInternalServerError, fmt.Errorf(\"error determining ControllerRing for request: %w\", err))\n\t}\n\n\t// Unfortunately, admission.Decoder / runtime.Decoder can't handle decoding into PartialObjectMetadata.\n\t// We are only interested in the metadata and webhooks always use json encoding, so let's simply decode ourselves.\n\tobj := &metav1.PartialObjectMetadata{}\n\tif err := json.Unmarshal(req.Object.Raw, obj); err != nil {\n\t\treturn admission.Errored(http.StatusInternalServerError, fmt.Errorf(\"error decoding object: %w\", err))\n\t}\n\n\tlabelShard := controllerRing.LabelShard()\n\n\t// Don't touch labels that the object already has, we can't simply reassign it because the active shard might still\n\t// be working on it.\n\tif obj.Labels[labelShard] != \"\" {\n\t\treturn admission.Allowed(\"object is already assigned\")\n\t}\n\n\tkeyFunc, err := key.FuncForResource(metav1.GroupResource{\n\t\tGroup:    req.Resource.Group,\n\t\tResource: req.Resource.Resource,\n\t}, controllerRing)\n\tif err != nil {\n\t\treturn admission.Errored(http.StatusBadRequest, fmt.Errorf(\"error determining hash key func for object: %w\", err))\n\t}\n\n\thashKey, err := keyFunc(obj)\n\tif err != nil {\n\t\treturn admission.Errored(http.StatusBadRequest, fmt.Errorf(\"error calculating hash key for object: %w\", err))\n\t}\n\tif hashKey == \"\" {\n\t\treturn admission.Allowed(\"object should not be assigned\")\n\t}\n\n\t// collect list of shards in the ring\n\tleaseList := &coordinationv1.LeaseList{}\n\tif err := h.Reader.List(ctx, leaseList, client.MatchingLabelsSelector{Selector: controllerRing.LeaseSelector()}); err != nil {\n\t\treturn admission.Errored(http.StatusInternalServerError, fmt.Errorf(\"error listing Leases for ControllerRing: %w\", err))\n\t}\n\n\t// get ring from cache and hash the object onto the ring\n\thashRing, _ := ring.FromLeases(controllerRing, leaseList, h.Clock.Now())\n\tshard := hashRing.Hash(hashKey)\n\tif shard == \"\" {\n\t\treturn admission.Allowed(\"there is no available shard\")\n\t}\n\n\tlog.V(1).Info(\"Assigning object for ControllerRing\", \"controllerRing\", client.ObjectKeyFromObject(controllerRing), \"shard\", shard)\n\n\tpatches := make([]jsonpatch.JsonPatchOperation, 0, 2)\n\tif obj.Labels == nil {\n\t\tpatches = append(patches, jsonpatch.NewOperation(\"add\", \"/metadata/labels\", map[string]string{}))\n\t}\n\t// If we reach here, the shard label is always missing. Otherwise, we would have exited early.\n\tpatches = append(patches, jsonpatch.NewOperation(\"add\", \"/metadata/labels/\"+rfc6901Encoder.Replace(labelShard), shard))\n\n\tif !ptr.Deref(req.DryRun, false) {\n\t\th.Metrics.ObserveAssignment(controllerRing.Name, metav1.GroupResource{Group: req.Resource.Group, Resource: req.Resource.Resource})\n\t}\n\n\treturn admission.Patched(\"assigning object\", patches...)\n}\n\n// ControllerRingForRequest returns the Ring object matching the requests' path.\nfunc ControllerRingForRequest(ctx context.Context, c client.Reader) (*shardingv1alpha1.ControllerRing, error) {\n\trequestPath, err := RequestPathFromContext(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcontrollerRing, err := ControllerRingForWebhookPath(requestPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := c.Get(ctx, client.ObjectKeyFromObject(controllerRing), controllerRing); err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting ControllerRing: %w\", err)\n\t}\n\n\treturn controllerRing, nil\n}\n\n// rfc6901Encoder can escape / characters in label keys for inclusion in JSON patch paths.\nvar rfc6901Encoder = strings.NewReplacer(\"~\", \"~0\", \"/\", \"~1\")\n"
  },
  {
    "path": "pkg/webhook/sharder/handler_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder_test\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"time\"\n\n\tjsonpatch \"github.com/evanphx/json-patch\"\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tgomegatypes \"github.com/onsi/gomega/types\"\n\tjsonpatchtypes \"gomodules.xyz/jsonpatch/v2\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/util/json\"\n\t\"k8s.io/utils/clock\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client/fake\"\n\t\"sigs.k8s.io/controller-runtime/pkg/webhook/admission\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\tutilclient \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/client\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/webhook/sharder\"\n)\n\nvar _ = Describe(\"Handler\", func() {\n\tconst controllerRingName = \"foo\"\n\n\tvar (\n\t\tctx context.Context\n\n\t\thandler admission.Handler\n\t\tmetrics *fakeMetrics\n\n\t\tcontrollerRing *shardingv1alpha1.ControllerRing\n\n\t\tmainObj       *corev1.Secret\n\t\tcontrolledObj *corev1.ConfigMap\n\n\t\tavailableShard *coordinationv1.Lease\n\n\t\tfakeClient client.Client\n\t)\n\n\tBeforeEach(func() {\n\t\tcontrollerRing = &shardingv1alpha1.ControllerRing{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tName: controllerRingName,\n\t\t\t},\n\t\t\tSpec: shardingv1alpha1.ControllerRingSpec{\n\t\t\t\tResources: []shardingv1alpha1.RingResource{{\n\t\t\t\t\tGroupResource: metav1.GroupResource{\n\t\t\t\t\t\tResource: \"secrets\",\n\t\t\t\t\t},\n\t\t\t\t\tControlledResources: []metav1.GroupResource{{\n\t\t\t\t\t\tResource: \"configmaps\",\n\t\t\t\t\t}},\n\t\t\t\t}},\n\t\t\t},\n\t\t}\n\n\t\tctx = NewContextWithRequestPath(context.Background(), &http.Request{\n\t\t\tURL: &url.URL{Path: \"/webhooks/sharder/controllerring/\" + controllerRingName},\n\t\t})\n\n\t\tmainObj = &corev1.Secret{\n\t\t\tTypeMeta:   metav1.TypeMeta{APIVersion: \"v1\", Kind: \"Secret\"},\n\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"foo\", Namespace: \"default\"},\n\t\t}\n\t\tcontrolledObj = &corev1.ConfigMap{\n\t\t\tTypeMeta: metav1.TypeMeta{APIVersion: \"v1\", Kind: \"ConfigMap\"},\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tNamespace: mainObj.Namespace,\n\t\t\t\tOwnerReferences: []metav1.OwnerReference{{\n\t\t\t\t\tAPIVersion: mainObj.APIVersion,\n\t\t\t\t\tKind:       mainObj.Kind,\n\t\t\t\t\tName:       mainObj.Name,\n\t\t\t\t\tController: ptr.To(true),\n\t\t\t\t}},\n\t\t\t},\n\t\t}\n\n\t\tfakeClock := &clock.RealClock{}\n\t\tavailableShard = &coordinationv1.Lease{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tName: \"shard-0\",\n\t\t\t\tLabels: map[string]string{\n\t\t\t\t\tshardingv1alpha1.LabelControllerRing: controllerRing.Name,\n\t\t\t\t},\n\t\t\t},\n\t\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\t\tHolderIdentity:       ptr.To(\"shard-0\"),\n\t\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-5 * time.Minute))),\n\t\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(fakeClock.Now().Add(-2 * time.Second))),\n\t\t\t},\n\t\t}\n\n\t\tfakeClient = fake.NewClientBuilder().\n\t\t\tWithScheme(utilclient.SharderScheme).\n\t\t\tWithObjects(controllerRing, availableShard).\n\t\t\tBuild()\n\n\t\tmetrics = &fakeMetrics{}\n\n\t\thandler = &Handler{\n\t\t\tReader:  fakeClient,\n\t\t\tClock:   fakeClock,\n\t\t\tMetrics: metrics,\n\t\t}\n\t})\n\n\tDescribe(\"#ControllerRingForRequest\", func() {\n\t\tIt(\"should return the ControllerRing matching the request\", func() {\n\t\t\tExpect(ControllerRingForRequest(ctx, fakeClient)).To(Equal(controllerRing))\n\t\t})\n\t})\n\n\tDescribe(\"#Handle\", func() {\n\t\tWhen(\"the request has an invalid path\", func() {\n\t\t\tBeforeEach(func() {\n\t\t\t\tctx = NewContextWithRequestPath(context.Background(), &http.Request{\n\t\t\t\t\tURL: &url.URL{Path: \"/webhooks/sharder/controllerring/\"},\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tIt(\"should return an error\", func() {\n\t\t\t\tExpect(handler.Handle(ctx, newRequest(mainObj))).To(beErrored(ContainSubstring(\"unexpected request path\")))\n\t\t\t})\n\t\t})\n\n\t\tWhen(\"the request is for a non-existing ControllerRing\", func() {\n\t\t\tBeforeEach(func() {\n\t\t\t\tctx = NewContextWithRequestPath(context.Background(), &http.Request{\n\t\t\t\t\tURL: &url.URL{Path: \"/webhooks/sharder/controllerring/not-existing\"},\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tIt(\"should return an error\", func() {\n\t\t\t\tExpect(handler.Handle(ctx, newRequest(mainObj))).To(beErrored(ContainSubstring(\"error getting ControllerRing\")))\n\t\t\t})\n\t\t})\n\n\t\tWhen(\"the request has an invalid object\", func() {\n\t\t\tIt(\"should return an error\", func() {\n\t\t\t\treq := admission.Request{}\n\t\t\t\treq.Object.Raw = []byte(\"foo\")\n\n\t\t\t\tExpect(handler.Handle(ctx, req)).To(beErrored(ContainSubstring(\"error decoding object\")))\n\t\t\t})\n\t\t})\n\n\t\tWhen(\"the request has an unrelated object\", func() {\n\t\t\tIt(\"should return an error\", func() {\n\t\t\t\tExpect(handler.Handle(ctx, newRequest(&corev1.Pod{}))).To(beErrored(ContainSubstring(\"not found in ControllerRing\")))\n\t\t\t})\n\t\t})\n\n\t\tWhen(\"the main object uses generateName\", func() {\n\t\t\tBeforeEach(func() {\n\t\t\t\tmainObj.Name = \"\"\n\t\t\t\tmainObj.GenerateName = \"test-\"\n\t\t\t})\n\n\t\t\tIt(\"should return an error\", func() {\n\t\t\t\tExpect(handler.Handle(ctx, newRequest(mainObj))).To(beErrored(ContainSubstring(\"generateName is not supported\")))\n\t\t\t})\n\t\t})\n\n\t\tWhen(\"the object is already assigned\", func() {\n\t\t\tBeforeEach(func() {\n\t\t\t\tmetav1.SetMetaDataLabel(&mainObj.ObjectMeta, controllerRing.LabelShard(), \"foo\")\n\t\t\t\tmetav1.SetMetaDataLabel(&controlledObj.ObjectMeta, controllerRing.LabelShard(), \"foo\")\n\t\t\t})\n\n\t\t\tIt(\"should do nothing\", func() {\n\t\t\t\tExpect(handler.Handle(ctx, newRequest(mainObj))).To(beAllowed(\"object is already assigned\"))\n\t\t\t\tExpect(handler.Handle(ctx, newRequest(controlledObj))).To(beAllowed(\"object is already assigned\"))\n\t\t\t})\n\t\t})\n\n\t\tWhen(\"there is no available shard\", func() {\n\t\t\tBeforeEach(func() {\n\t\t\t\tavailableShard.Spec.HolderIdentity = nil\n\t\t\t\tExpect(fakeClient.Update(ctx, availableShard)).To(Succeed())\n\t\t\t})\n\n\t\t\tIt(\"should do nothing\", func() {\n\t\t\t\tExpect(handler.Handle(ctx, newRequest(mainObj))).To(beAllowed(\"there is no available shard\"))\n\t\t\t\tExpect(handler.Handle(ctx, newRequest(controlledObj))).To(beAllowed(\"there is no available shard\"))\n\t\t\t})\n\t\t})\n\n\t\tWhen(\"the controlled object has no controller reference\", func() {\n\t\t\tBeforeEach(func() {\n\t\t\t\tcontrolledObj.OwnerReferences = nil\n\t\t\t})\n\n\t\t\tIt(\"should do nothing\", func() {\n\t\t\t\tExpect(handler.Handle(ctx, newRequest(controlledObj))).To(beAllowed(\"object should not be assigned\"))\n\t\t\t})\n\t\t})\n\n\t\tWhen(\"the object has no labels\", func() {\n\t\t\tIt(\"should add labels and assign the object\", func() {\n\t\t\t\tres := handler.Handle(ctx, newRequest(mainObj))\n\t\t\t\tExpect(res).To(bePatched())\n\t\t\t\tExpect(applyPatches(mainObj, res.Patches)).To(HaveLabelWithValue(controllerRing.LabelShard(), availableShard.Name))\n\t\t\t\tExpect(metrics.assignments).To(Equal(1))\n\n\t\t\t\tres = handler.Handle(ctx, newRequest(controlledObj))\n\t\t\t\tExpect(res).To(bePatched())\n\t\t\t\tExpect(applyPatches(controlledObj, res.Patches)).To(HaveLabelWithValue(controllerRing.LabelShard(), availableShard.Name))\n\t\t\t\tExpect(metrics.assignments).To(Equal(2))\n\t\t\t})\n\t\t})\n\n\t\tWhen(\"the object has other labels\", func() {\n\t\t\tBeforeEach(func() {\n\t\t\t\tmetav1.SetMetaDataLabel(&mainObj.ObjectMeta, \"foo\", \"bar\")\n\t\t\t\tmetav1.SetMetaDataLabel(&controlledObj.ObjectMeta, \"foo\", \"bar\")\n\t\t\t})\n\n\t\t\tIt(\"should keep existing labels and assign the object\", func() {\n\t\t\t\tres := handler.Handle(ctx, newRequest(mainObj))\n\t\t\t\tExpect(res).To(bePatched())\n\t\t\t\tExpect(applyPatches(mainObj, res.Patches)).To(And(\n\t\t\t\t\tHaveLabelWithValue(\"foo\", \"bar\"),\n\t\t\t\t\tHaveLabelWithValue(controllerRing.LabelShard(), availableShard.Name),\n\t\t\t\t))\n\n\t\t\t\tres = handler.Handle(ctx, newRequest(controlledObj))\n\t\t\t\tExpect(res).To(bePatched())\n\t\t\t\tExpect(applyPatches(controlledObj, res.Patches)).To(And(\n\t\t\t\t\tHaveLabelWithValue(\"foo\", \"bar\"),\n\t\t\t\t\tHaveLabelWithValue(controllerRing.LabelShard(), availableShard.Name),\n\t\t\t\t))\n\t\t\t})\n\t\t})\n\n\t\tWhen(\"the request is dry-run\", func() {\n\t\t\tIt(\"should not observe metrics\", func() {\n\t\t\t\treq := newRequest(mainObj)\n\t\t\t\treq.DryRun = ptr.To(true)\n\t\t\t\tExpect(handler.Handle(ctx, req)).To(bePatched())\n\t\t\t\tExpect(metrics.assignments).To(BeZero())\n\t\t\t})\n\t\t})\n\t})\n})\n\nfunc newRequest(obj client.Object) admission.Request {\n\tGinkgoHelper()\n\n\tvar gvr metav1.GroupVersionResource\n\tswitch obj.(type) {\n\tcase *corev1.Secret:\n\t\tgvr = metav1.GroupVersionResource{Group: \"\", Version: \"v1\", Resource: \"secrets\"}\n\tcase *corev1.ConfigMap:\n\t\tgvr = metav1.GroupVersionResource{Group: \"\", Version: \"v1\", Resource: \"configmaps\"}\n\tcase *corev1.Pod:\n\t\tgvr = metav1.GroupVersionResource{Group: \"\", Version: \"v1\", Resource: \"pods\"}\n\tdefault:\n\t\tFail(\"unknown object type\")\n\t}\n\n\treq := admission.Request{}\n\treq.Resource = gvr\n\n\tvar err error\n\treq.Object.Raw, err = json.Marshal(obj)\n\tExpect(err).NotTo(HaveOccurred())\n\n\treturn req\n}\n\nfunc beAllowed(message any) gomegatypes.GomegaMatcher {\n\treturn And(\n\t\tHaveField(\"Patches\", BeEmpty()),\n\t\tHaveField(\"AdmissionResponse\", And(\n\t\t\tHaveField(\"Allowed\", BeTrue()),\n\t\t\tHaveField(\"Result.Message\", message),\n\t\t)),\n\t)\n}\n\nfunc bePatched() gomegatypes.GomegaMatcher {\n\treturn And(\n\t\tHaveField(\"Patches\", Not(BeEmpty())),\n\t\tHaveField(\"AdmissionResponse\", And(\n\t\t\tHaveField(\"Allowed\", BeTrue()),\n\t\t\tHaveField(\"Result.Message\", \"assigning object\"),\n\t\t)),\n\t)\n}\n\nfunc beErrored(message any) gomegatypes.GomegaMatcher {\n\treturn And(\n\t\tHaveField(\"Patches\", BeEmpty()),\n\t\tHaveField(\"AdmissionResponse\", And(\n\t\t\tHaveField(\"Allowed\", BeFalse()),\n\t\t\tHaveField(\"Result.Message\", message),\n\t\t)),\n\t)\n}\n\nfunc applyPatches[T client.Object](obj T, patches []jsonpatchtypes.Operation) T {\n\tGinkgoHelper()\n\n\trawObj, err := json.Marshal(obj)\n\tExpect(err).NotTo(HaveOccurred())\n\n\trawPatch, err := json.Marshal(patches)\n\tExpect(err).NotTo(HaveOccurred())\n\n\tpatch, err := jsonpatch.DecodePatch(rawPatch)\n\tExpect(err).NotTo(HaveOccurred())\n\n\trawPatchedObj, err := patch.Apply(rawObj)\n\tExpect(err).NotTo(HaveOccurred())\n\n\tpatchedObj := obj.DeepCopyObject().(T)\n\tExpect(json.Unmarshal(rawPatchedObj, patchedObj)).To(Succeed())\n\n\treturn patchedObj\n}\n\ntype fakeMetrics struct {\n\tassignments int\n}\n\nfunc (f *fakeMetrics) ObserveAssignment(string, metav1.GroupResource) {\n\tf.assignments++\n}\n"
  },
  {
    "path": "pkg/webhook/sharder/metrics.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder\n\nimport (\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\n\tshardingmetrics \"github.com/timebertt/kubernetes-controller-sharding/pkg/metrics\"\n)\n\ntype Metrics interface {\n\tObserveAssignment(controllerRingName string, gr metav1.GroupResource)\n}\n\ntype realMetrics struct{}\n\nfunc (realMetrics) ObserveAssignment(controllerRingName string, gr metav1.GroupResource) {\n\tshardingmetrics.AssignmentsTotal.WithLabelValues(controllerRingName, gr.Group, gr.Resource).Inc()\n}\n"
  },
  {
    "path": "pkg/webhook/sharder/sharder_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestSharder(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Sharder Webhook Suite\")\n}\n"
  },
  {
    "path": "test/e2e/checksum_controller_test.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage e2e\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"maps\"\n\t\"strconv\"\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tadmissionregistrationv1 \"k8s.io/api/admissionregistration/v1\"\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tautoscalingv1 \"k8s.io/api/autoscaling/v1\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\t\"k8s.io/apimachinery/pkg/api/meta\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t. \"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nconst (\n\tchecksumControllerName = \"checksum-controller\"\n\tnamePrefixChecksums    = \"checksums-\"\n\n\tobjectCount = 100\n)\n\nvar _ = Describe(\"Checksum Controller\", Label(checksumControllerName), func() {\n\tDescribe(\"setup\", Ordered, func() {\n\t\titDeploymentShouldBeAvailable(ptr.To(&appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: \"sharder\", Namespace: shardingv1alpha1.NamespaceSystem}}), 2)\n\t\titDeploymentShouldBeAvailable(&controllerDeployment, 3)\n\t\titControllerRingShouldBeReady()\n\t\titShouldRecognizeReadyShardLeases(3)\n\n\t\tIt(\"there should not be any shard leases other than the 3 ready leases\", func(ctx SpecContext) {\n\t\t\tleaseList := &coordinationv1.LeaseList{}\n\t\t\tEventually(ctx, ObjectList(leaseList, client.InNamespace(namespace.Name),\n\t\t\t\tclient.MatchingLabels{shardingv1alpha1.LabelControllerRing: controllerRing.Name},\n\t\t\t)).Should(HaveNames(shards...))\n\t\t}, SpecTimeout(ShortTimeout))\n\n\t\tIt(\"should create the MutatingWebhookConfiguration\", func(ctx SpecContext) {\n\t\t\twebhookConfig := &admissionregistrationv1.MutatingWebhookConfiguration{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"controllerring-\" + controllerRing.Name},\n\t\t\t}\n\t\t\tEventually(ctx, Object(webhookConfig)).Should(And(\n\t\t\t\tHaveLabelWithValue(shardingv1alpha1.LabelControllerRing, controllerRing.Name),\n\t\t\t\tHaveField(\"Webhooks\", ConsistOf(And(\n\t\t\t\t\tHaveField(\"NamespaceSelector\", Equal(&metav1.LabelSelector{\n\t\t\t\t\t\tMatchLabels: map[string]string{corev1.LabelMetadataName: namespace.Name},\n\t\t\t\t\t})),\n\t\t\t\t\tHaveField(\"ObjectSelector\", Equal(&metav1.LabelSelector{\n\t\t\t\t\t\tMatchExpressions: []metav1.LabelSelectorRequirement{{\n\t\t\t\t\t\t\tKey:      controllerRing.LabelShard(),\n\t\t\t\t\t\t\tOperator: metav1.LabelSelectorOpDoesNotExist,\n\t\t\t\t\t\t}},\n\t\t\t\t\t})),\n\t\t\t\t\tHaveField(\"Rules\", ConsistOf(\n\t\t\t\t\t\tHaveField(\"Resources\", ConsistOf(\"secrets\")),\n\t\t\t\t\t\tHaveField(\"Resources\", ConsistOf(\"configmaps\")),\n\t\t\t\t\t)),\n\t\t\t\t))),\n\t\t\t))\n\t\t}, SpecTimeout(ShortTimeout))\n\t})\n\n\tDescribe(\"creating a secret\", Ordered, func() {\n\t\tvar (\n\t\t\tsecret *corev1.Secret\n\t\t\tshard  string\n\t\t)\n\n\t\titControllerRingShouldBeReady()\n\t\titShouldRecognizeReadyShardLeases(3)\n\n\t\tIt(\"should assign the main object to a healthy shard\", func(ctx SpecContext) {\n\t\t\t// Verify that the sharder successfully injects the shard label.\n\t\t\t// The webhook has failurePolicy=Ignore, so we might need to retry the creation until the injection succeeds.\n\t\t\tEventually(ctx, func(g Gomega) *corev1.Secret {\n\t\t\t\tsecret = newSecret(\"foo-\" + test.RandomSuffix())\n\t\t\t\tg.Expect(testClient.Create(ctx, secret)).To(Succeed())\n\t\t\t\treturn secret\n\t\t\t}).Should(And(\n\t\t\t\tHaveLabelWithValue(controllerRing.LabelShard(), BeElementOf(shards)),\n\t\t\t\tNot(HaveLabel(controllerRing.LabelDrain())),\n\t\t\t))\n\t\t\tshard = secret.Labels[controllerRing.LabelShard()]\n\n\t\t\tlog.Info(\"Created object\", \"secret\", client.ObjectKeyFromObject(secret), \"shard\", shard)\n\t\t}, SpecTimeout(MediumTimeout))\n\n\t\tIt(\"should assign the controlled ConfigMap to the same shard\", func(ctx SpecContext) {\n\t\t\tconfigMap := &corev1.ConfigMap{}\n\t\t\tconfigMap.Name = namePrefixChecksums + secret.Name\n\t\t\tconfigMap.Namespace = secret.Namespace\n\n\t\t\tEventually(ctx, Object(configMap)).Should(And(\n\t\t\t\tHaveLabelWithValue(controllerRing.LabelShard(), Equal(shard)),\n\t\t\t\tNot(HaveLabel(controllerRing.LabelDrain())),\n\t\t\t))\n\t\t}, SpecTimeout(MediumTimeout))\n\t})\n\n\tDescribe(\"creating many secrets\", Ordered, func() {\n\t\titControllerRingShouldBeReady()\n\t\titShouldRecognizeReadyShardLeases(3)\n\n\t\titCreateSecrets()\n\n\t\tIt(\"should correctly map controlled objects\", func(ctx SpecContext) {\n\t\t\tvar usedShards sets.Set[string]\n\t\t\tEventually(ctx, func(g Gomega) {\n\t\t\t\tsecretsList := &corev1.SecretList{}\n\t\t\t\tg.Expect(ObjectList(secretsList, client.InNamespace(namespace.Name), client.MatchingLabels(testRunLabels))()).To(HaveField(\"Items\", HaveLen(objectCount)))\n\n\t\t\t\tconfigMapList := &corev1.ConfigMapList{}\n\t\t\t\tg.Expect(ObjectList(configMapList, client.InNamespace(namespace.Name), client.MatchingLabels(testRunLabels))()).To(HaveField(\"Items\", HaveLen(objectCount)))\n\t\t\t\tconfigMaps := toMapOfConfigMap(configMapList.Items)\n\n\t\t\t\tusedShards = sets.New[string]()\n\t\t\t\tfor _, secret := range secretsList.Items {\n\t\t\t\t\tg.Expect(secret).To(HaveLabelWithValue(controllerRing.LabelShard(), BeElementOf(shards)))\n\t\t\t\t\tg.Expect(secret).NotTo(HaveLabel(controllerRing.LabelDrain()))\n\n\t\t\t\t\tconfigMap := configMaps[namePrefixChecksums+secret.Name]\n\t\t\t\t\tg.Expect(configMap).NotTo(BeNil(), \"there should be a checksum ConfigMap for Secret %s\", secret.Name)\n\n\t\t\t\t\tg.Expect(configMap).NotTo(HaveLabel(controllerRing.LabelDrain()))\n\t\t\t\t\tg.Expect(configMap.Labels[controllerRing.LabelShard()]).To(Equal(secret.Labels[controllerRing.LabelShard()]),\n\t\t\t\t\t\t\"ConfigMap %s should be assigned to the same shard as the owning Secret\", configMap.Name)\n\t\t\t\t\tusedShards.Insert(secret.Labels[controllerRing.LabelShard()])\n\t\t\t\t}\n\t\t\t}).Should(Succeed(), \"ConfigMaps should be assigned to the same shard as the owning Secrets\")\n\n\t\t\tExpect(usedShards.UnsortedList()).To(ConsistOf(shards), \"should use all available shards\")\n\t\t}, SpecTimeout(MediumTimeout))\n\t})\n\n\tdescribeScaleController(\"adding a shard\", 4)\n\n\tdescribeScaleController(\"removing a shard\", 2)\n\n\tDescribe(\"graceful shard termination\", Ordered, func() {\n\t\tvar lease *coordinationv1.Lease\n\n\t\tBeforeAll(func() {\n\t\t\tlease = newLease(60)\n\t\t})\n\n\t\titControllerRingShouldBeReady()\n\n\t\titCreateShardLease(&lease)\n\t\titShouldReportShardLeaseState(&lease, leases.Ready)\n\t\titControllerRingShouldHaveAvailableShards(4)\n\n\t\tIt(\"release the shard lease\", func(ctx SpecContext) {\n\t\t\tpatch := client.MergeFrom(lease.DeepCopy())\n\t\t\tlease.Spec.HolderIdentity = nil\n\t\t\tExpect(testClient.Patch(ctx, lease, patch)).To(Succeed())\n\t\t}, SpecTimeout(ShortTimeout))\n\n\t\titShouldReportShardLeaseState(&lease, leases.Dead)\n\t\titControllerRingShouldHaveAvailableShards(3)\n\t})\n\n\tDescribe(\"shard failure detection\", Ordered, func() {\n\t\tvar lease *coordinationv1.Lease\n\n\t\tBeforeAll(func() {\n\t\t\tlease = newLease(10)\n\t\t})\n\n\t\titControllerRingShouldBeReady()\n\n\t\titCreateShardLease(&lease)\n\t\titShouldReportShardLeaseState(&lease, leases.Ready)\n\t\titControllerRingShouldHaveAvailableShards(4)\n\n\t\tIt(\"should transition the shard lease to state expired\", func(ctx SpecContext) {\n\t\t\tEventually(ctx, Object(lease)).Should(\n\t\t\t\tHaveLabelWithValue(shardingv1alpha1.LabelState, leases.Expired.String()),\n\t\t\t)\n\t\t}, SpecTimeout(15*time.Second))\n\n\t\tIt(\"should acquire the shard lease\", func(ctx SpecContext) {\n\t\t\tEventually(ctx, Object(lease)).Should(And(\n\t\t\t\tHaveField(\"Spec.HolderIdentity\", HaveValue(Equal(shardingv1alpha1.IdentityShardLeaseController))),\n\t\t\t\tHaveLabelWithValue(shardingv1alpha1.LabelState, leases.Dead.String()),\n\t\t\t), \"lease should be acquired by sharder\")\n\t\t}, SpecTimeout(15*time.Second))\n\n\t\titControllerRingShouldHaveAvailableShards(3)\n\t})\n})\n\nfunc describeScaleController(text string, replicas int32) {\n\tDescribe(text, Ordered, func() {\n\t\titControllerRingShouldHaveAvailableShards(3)\n\t\titShouldRecognizeReadyShardLeases(3)\n\n\t\titCreateSecrets()\n\t\titShouldAssignObjectsToAvailableShards()\n\n\t\titScaleController(replicas)\n\t\titDeploymentShouldBeAvailable(&controllerDeployment, replicas)\n\t\titControllerRingShouldHaveAvailableShards(replicas)\n\t\titShouldRecognizeReadyShardLeases(int(replicas))\n\n\t\titShouldAssignObjectsToAvailableShards()\n\t})\n}\n\nfunc newSecret(name string) *corev1.Secret {\n\treturn &corev1.Secret{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      name,\n\t\t\tNamespace: namespace.Name,\n\t\t\tLabels:    maps.Clone(testRunLabels),\n\t\t},\n\t}\n}\n\nfunc itDeploymentShouldBeAvailable(deployment **appsv1.Deployment, expectedReplicas int32) {\n\tGinkgoHelper()\n\n\tname := \"controller\"\n\tif *deployment != nil {\n\t\tname = (*deployment).Name\n\t}\n\n\tIt(fmt.Sprintf(\"the %s Deployment should be available\", name), func(ctx SpecContext) {\n\t\tEventually(ctx, Object(*deployment)).Should(And(\n\t\t\tHaveField(\"Spec.Replicas\", HaveValue(BeEquivalentTo(expectedReplicas))),\n\t\t\tHaveField(\"Status.Replicas\", BeEquivalentTo(expectedReplicas)),\n\t\t\tHaveField(\"Status.AvailableReplicas\", BeEquivalentTo(expectedReplicas)),\n\t\t))\n\t}, SpecTimeout(ShortTimeout))\n}\n\nfunc itControllerRingShouldBeReady() {\n\tGinkgoHelper()\n\n\tIt(\"the ControllerRing should be ready\", func(ctx SpecContext) {\n\t\tEventually(ctx, Object(controllerRing)).Should(And(\n\t\t\tHaveField(\"Status.Shards\", BeEquivalentTo(3)),\n\t\t\tHaveField(\"Status.AvailableShards\", BeEquivalentTo(3)),\n\t\t\tHaveField(\"Status.Conditions\", ConsistOf(\n\t\t\t\tMatchCondition(\n\t\t\t\t\tOfType(shardingv1alpha1.ControllerRingReady),\n\t\t\t\t\tWithStatus(metav1.ConditionTrue),\n\t\t\t\t),\n\t\t\t)),\n\t\t))\n\t}, SpecTimeout(ShortTimeout))\n}\n\nfunc itControllerRingShouldHaveAvailableShards(expectedAvailableShards int32) {\n\tGinkgoHelper()\n\n\tIt(fmt.Sprintf(\"the ControllerRing should be ready and should have %d available shards\", expectedAvailableShards), func(ctx SpecContext) {\n\t\tEventually(ctx, Object(controllerRing)).Should(And(\n\t\t\tHaveField(\"Status.AvailableShards\", BeEquivalentTo(expectedAvailableShards)),\n\t\t\tHaveField(\"Status.Conditions\", ConsistOf(\n\t\t\t\tMatchCondition(\n\t\t\t\t\tOfType(shardingv1alpha1.ControllerRingReady),\n\t\t\t\t\tWithStatus(metav1.ConditionTrue),\n\t\t\t\t),\n\t\t\t)),\n\t\t))\n\t}, SpecTimeout(ShortTimeout))\n}\n\nvar shards []string\n\nfunc itShouldRecognizeReadyShardLeases(expectedCount int) {\n\tGinkgoHelper()\n\n\tIt(fmt.Sprintf(\"should recognize %d ready shard leases\", expectedCount), func(ctx SpecContext) {\n\t\tleaseList := &coordinationv1.LeaseList{}\n\t\tEventually(ctx, ObjectList(leaseList, client.InNamespace(namespace.Name), client.MatchingLabels{\n\t\t\tshardingv1alpha1.LabelControllerRing: controllerRing.Name,\n\t\t\tshardingv1alpha1.LabelState:          leases.Ready.String(),\n\t\t})).Should(HaveField(\"Items\", HaveLen(expectedCount)))\n\n\t\tshards = make([]string, len(leaseList.Items))\n\t\tfor i, lease := range leaseList.Items {\n\t\t\tshards[i] = lease.Name\n\t\t}\n\t}, SpecTimeout(ShortTimeout))\n}\n\nfunc itCreateShardLease(lease **coordinationv1.Lease) {\n\tGinkgoHelper()\n\n\tIt(\"create a new shard lease\", func(ctx SpecContext) {\n\t\tmicroNow := metav1.NewMicroTime(time.Now())\n\t\t(*lease).Spec.AcquireTime = ptr.To(microNow)\n\t\t(*lease).Spec.RenewTime = ptr.To(microNow)\n\n\t\tExpect(testClient.Create(ctx, *lease)).To(Succeed())\n\t}, SpecTimeout(ShortTimeout))\n}\n\nfunc itShouldReportShardLeaseState(lease **coordinationv1.Lease, state leases.ShardState) {\n\tGinkgoHelper()\n\n\tIt(\"should mark the shard lease as \"+state.String(), func(ctx SpecContext) {\n\t\tEventually(ctx, Object(*lease)).Should(\n\t\t\tHaveLabelWithValue(shardingv1alpha1.LabelState, state.String()),\n\t\t)\n\t}, SpecTimeout(ShortTimeout))\n}\n\nfunc itCreateSecrets() {\n\tGinkgoHelper()\n\n\tIt(fmt.Sprintf(\"create %d secrets\", objectCount), func(ctx SpecContext) {\n\t\tfor i := 0; i < objectCount; i++ {\n\t\t\tsecret := newSecret(\"foo-\" + strconv.Itoa(i))\n\t\t\tExpect(testClient.Create(ctx, secret)).To(Succeed(), \"should create secret %s\", secret.Name)\n\t\t}\n\t}, SpecTimeout(MediumTimeout))\n}\n\nfunc itScaleController(replicas int32) {\n\tGinkgoHelper()\n\n\tIt(fmt.Sprintf(\"scale the controller to %d replicas\", replicas), func(ctx SpecContext) {\n\t\tscaleController(ctx, replicas)\n\t}, NodeTimeout(ShortTimeout))\n}\n\nfunc scaleController(ctx context.Context, replicas int32) {\n\tGinkgoHelper()\n\n\tpatch := client.MergeFrom(&autoscalingv1.Scale{})\n\tscale := &autoscalingv1.Scale{Spec: autoscalingv1.ScaleSpec{Replicas: replicas}}\n\tExpect(testClient.SubResource(\"scale\").Patch(ctx, controllerDeployment, patch, client.WithSubResourceBody(scale), &client.SubResourcePatchOptions{})).To(Succeed())\n\n\tlog.Info(\"Scaled controller\", \"replicas\", replicas)\n}\n\nfunc itShouldAssignObjectsToAvailableShards() {\n\tGinkgoHelper()\n\n\tIt(\"should assign the Secrets to the available shards\", func(ctx SpecContext) {\n\t\teventuallyShouldAssignObjectsToAvailableShards(ctx, &corev1.SecretList{})\n\t}, NodeTimeout(MediumTimeout))\n\n\tIt(\"should assign the controlled ConfigMaps to the available shards\", func(ctx SpecContext) {\n\t\teventuallyShouldAssignObjectsToAvailableShards(ctx, &corev1.ConfigMapList{})\n\t}, NodeTimeout(MediumTimeout))\n}\n\nfunc eventuallyShouldAssignObjectsToAvailableShards(ctx context.Context, list client.ObjectList) {\n\tGinkgoHelper()\n\n\tEventually(ctx, func(g Gomega) {\n\t\tg.Expect(ObjectList(list, client.InNamespace(namespace.Name), client.MatchingLabels(testRunLabels))()).To(HaveField(\"Items\", HaveLen(objectCount)))\n\n\t\tusedShards := sets.New[string]()\n\t\tExpect(meta.EachListItem(list, func(obj runtime.Object) error {\n\t\t\tg.Expect(obj).To(HaveLabelWithValue(controllerRing.LabelShard(), Not(BeEmpty())), \"object %T %s should be assigned\")\n\t\t\tg.Expect(obj).NotTo(HaveLabel(controllerRing.LabelDrain()), \"object %T %s should not have drain label\")\n\n\t\t\tusedShards.Insert(obj.(client.Object).GetLabels()[controllerRing.LabelShard()])\n\t\t\treturn nil\n\t\t})).To(Succeed())\n\n\t\tg.Expect(usedShards.UnsortedList()).To(ConsistOf(shards), \"should use all available shards\")\n\t}).Should(Succeed())\n}\n\nfunc newLease(leaseDurationSeconds int32) *coordinationv1.Lease {\n\tname := \"test-\" + test.RandomSuffix()\n\n\treturn &coordinationv1.Lease{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      name,\n\t\t\tNamespace: namespace.Name,\n\t\t\tLabels: map[string]string{\n\t\t\t\tshardingv1alpha1.LabelControllerRing: controllerRing.Name,\n\t\t\t},\n\t\t},\n\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\tHolderIdentity:       ptr.To(name),\n\t\t\tLeaseDurationSeconds: ptr.To[int32](leaseDurationSeconds),\n\t\t},\n\t}\n}\n\nfunc toMapOfConfigMap(configMaps []corev1.ConfigMap) map[string]*corev1.ConfigMap {\n\tout := make(map[string]*corev1.ConfigMap, len(configMaps))\n\tfor _, configMap := range configMaps {\n\t\tout[configMap.Name] = &configMap\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "test/e2e/e2e_suite_test.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage e2e\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"maps\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\trbacv1 \"k8s.io/api/rbac/v1\"\n\t\"k8s.io/apimachinery/pkg/api/meta\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\tclientgoscheme \"k8s.io/client-go/kubernetes/scheme\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client/config\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nfunc TestE2E(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Controller Sharding E2E Test Suite\")\n}\n\nconst (\n\ttestID = \"e2e-controller-sharding\"\n\n\tShortTimeout  = 10 * time.Second\n\tMediumTimeout = time.Minute\n)\n\nvar (\n\tlog logr.Logger\n\n\ttestClient client.Client\n\n\ttestRunID     string\n\ttestRunLabels map[string]string\n)\n\nvar _ = BeforeSuite(func() {\n\tlog = zap.New(zap.UseDevMode(true), zap.WriteTo(GinkgoWriter)).WithName(testID)\n\n\trestConfig, err := config.GetConfig()\n\tExpect(err).NotTo(HaveOccurred())\n\n\tscheme := runtime.NewScheme()\n\tschemeBuilder := runtime.NewSchemeBuilder(\n\t\tclientgoscheme.AddToScheme,\n\t\tshardingv1alpha1.AddToScheme,\n\t)\n\tExpect(schemeBuilder.AddToScheme(scheme)).To(Succeed())\n\n\ttestClient, err = client.New(restConfig, client.Options{Scheme: scheme})\n\tExpect(err).NotTo(HaveOccurred())\n\n\tclientContext, clientCancel := context.WithCancel(context.Background())\n\tkomega.SetClient(testClient)\n\tkomega.SetContext(clientContext)\n\tDeferCleanup(clientCancel)\n\n\ttestRunID = testID + \"-\" + test.RandomSuffix()\n\ttestRunLabels = map[string]string{\n\t\ttestID: testRunID,\n\t}\n\tlog = log.WithValues(\"testRun\", testRunID)\n})\n\nvar (\n\tcontrollerRing *shardingv1alpha1.ControllerRing\n\tnamespace      *corev1.Namespace\n\n\tcontrollerDeployment *appsv1.Deployment\n)\n\nvar _ = BeforeEach(func(ctx SpecContext) {\n\tBy(\"Set up test Namespace\")\n\tnamespace = &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{\n\t\tGenerateName: testRunID + \"-\",\n\t\tLabels:       maps.Clone(testRunLabels),\n\t}}\n\n\t// We create a dedicated test namespace and clean it up for every test case to ensure a clean test environment.\n\tExpect(testClient.Create(ctx, namespace)).To(Succeed())\n\tlog.Info(\"Created test Namespace\", \"namespace\", namespace.Name)\n\n\tDeferCleanup(func(ctx SpecContext) {\n\t\tBy(\"Delete test Namespace\")\n\t\tEventually(ctx, func() error {\n\t\t\treturn testClient.Delete(ctx, namespace)\n\t\t}).Should(Or(Succeed(), BeNotFoundError()))\n\t}, NodeTimeout(MediumTimeout))\n\n\tBy(\"Set up test ControllerRing\")\n\t// Deploy a dedicated ControllerRing instance for this test case\n\tdefaultControllerRing := &shardingv1alpha1.ControllerRing{ObjectMeta: metav1.ObjectMeta{Name: checksumControllerName}}\n\tExpect(komega.Get(defaultControllerRing)()).To(Succeed())\n\n\tcontrollerRing = defaultControllerRing.DeepCopy()\n\tcontrollerRing.Name = namespace.Name\n\tcontrollerRing.ResourceVersion = \"\"\n\tmaps.Copy(controllerRing.Labels, testRunLabels)\n\tcontrollerRing.Spec.NamespaceSelector.MatchLabels[corev1.LabelMetadataName] = namespace.Name\n\tExpect(testClient.Create(ctx, controllerRing)).To(Succeed())\n\n\tDeferCleanup(func(ctx SpecContext) {\n\t\tBy(\"Delete test ControllerRing\")\n\t\tEventually(ctx, func() error {\n\t\t\treturn testClient.Delete(ctx, controllerRing)\n\t\t}).Should(Or(Succeed(), BeNotFoundError()))\n\t}, NodeTimeout(ShortTimeout))\n\n\tBy(\"Set up test controller\")\n\tcontrollerDeployment = &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Namespace: namespace.Name, Name: checksumControllerName}}\n\n\t// Deploy a dedicated controller instance to this test case's namespace.\n\t// Copy all relevant objects from the default namespace.\n\tfor _, objList := range []client.ObjectList{\n\t\t&appsv1.DeploymentList{},\n\t\t&corev1.ServiceAccountList{},\n\t\t&rbacv1.RoleList{},\n\t\t&rbacv1.RoleBindingList{},\n\t} {\n\t\tExpect(testClient.List(ctx, objList, client.InNamespace(metav1.NamespaceDefault), client.MatchingLabels{\"app.kubernetes.io/component\": checksumControllerName})).\n\t\t\tShould(Succeed(), \"should list %T in default namespace\", objList)\n\n\t\tExpect(meta.EachListItem(objList, func(object runtime.Object) error {\n\t\t\tobj := object.DeepCopyObject().(client.Object)\n\t\t\tobj.SetNamespace(namespace.Name)\n\t\t\tobj.SetResourceVersion(\"\")\n\n\t\t\tswitch o := obj.(type) {\n\t\t\tcase *appsv1.Deployment:\n\t\t\t\to.Spec.Replicas = ptr.To[int32](3)\n\t\t\t\to.Spec.Template.Spec.Containers[0].Args = append(o.Spec.Template.Spec.Containers[0].Args,\n\t\t\t\t\t\"--controllerring=\"+controllerRing.Name,\n\t\t\t\t\t\"--namespace=\"+namespace.Name,\n\t\t\t\t)\n\t\t\tcase *rbacv1.RoleBinding:\n\t\t\t\to.Subjects[0].Namespace = namespace.Name\n\t\t\t}\n\n\t\t\tif err := testClient.Create(ctx, obj); err != nil {\n\t\t\t\treturn fmt.Errorf(\"error copying object %T %q to %s namespace: %w\", obj, client.ObjectKeyFromObject(obj), namespace.Name, err)\n\t\t\t}\n\t\t\treturn nil\n\t\t})).To(Succeed(), \"should copy %T\", objList)\n\t}\n}, NodeTimeout(MediumTimeout), OncePerOrdered)\n"
  },
  {
    "path": "test/integration/shard/controller/controller_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/cache\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\tmetricsserver \"sigs.k8s.io/controller-runtime/pkg/metrics/server\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/test/integration/shard/controller\"\n)\n\nfunc TestController(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Shard Controller Integration Test Suite\")\n}\n\nconst testID = \"shard-controller-test\"\n\nvar (\n\tlog logr.Logger\n\n\ttestClient client.Client\n\n\tcontrollerRingName, shardName string\n\tshardLabel, drainLabel        string\n\n\ttestRunID string\n)\n\nvar _ = BeforeSuite(func(ctx SpecContext) {\n\tlogf.SetLogger(zap.New(zap.UseDevMode(true), zap.WriteTo(GinkgoWriter)))\n\tlog = logf.Log.WithName(testID)\n\n\tBy(\"Start test environment\")\n\ttestEnv := &envtest.Environment{}\n\n\trestConfig, err := testEnv.Start()\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(restConfig).NotTo(BeNil())\n\n\tDeferCleanup(func() {\n\t\tBy(\"Stop test environment\")\n\t\tExpect(testEnv.Stop()).To(Succeed())\n\t})\n\n\tBy(\"Create test clients\")\n\ttestClient, err = client.New(restConfig, client.Options{})\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(testClient).NotTo(BeNil())\n\n\tclientContext, clientCancel := context.WithCancel(context.Background())\n\tkomega.SetClient(testClient)\n\tkomega.SetContext(clientContext)\n\tDeferCleanup(clientCancel)\n\n\tBy(\"Create test Namespace\")\n\ttestNamespace := &corev1.Namespace{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tGenerateName: testID + \"-\",\n\t\t},\n\t}\n\tExpect(testClient.Create(ctx, testNamespace)).To(Succeed())\n\tlog.Info(\"Created Namespace for test\", \"namespaceName\", testNamespace.Name)\n\ttestRunID = testNamespace.Name\n\tlog = log.WithValues(\"testRunID\", testRunID)\n\n\tcontrollerRingName = testRunID\n\tshardName = testRunID\n\tshardLabel = \"shard.alpha.sharding.timebertt.dev/\" + controllerRingName\n\tdrainLabel = \"drain.alpha.sharding.timebertt.dev/\" + controllerRingName\n\n\tDeferCleanup(func(ctx SpecContext) {\n\t\tBy(\"Delete test Namespace\")\n\t\tExpect(testClient.Delete(ctx, testNamespace)).To(Or(Succeed(), BeNotFoundError()))\n\t}, NodeTimeout(time.Minute))\n\n\tBy(\"Setup manager\")\n\tmgr, err := manager.New(restConfig, manager.Options{\n\t\tMetrics: metricsserver.Options{BindAddress: \"0\"},\n\t\tCache: cache.Options{\n\t\t\tDefaultNamespaces: map[string]cache.Config{testNamespace.Name: {}},\n\t\t},\n\t})\n\tExpect(err).NotTo(HaveOccurred())\n\n\tBy(\"Register controller\")\n\tExpect((&Reconciler{}).AddToManager(mgr, controllerRingName, shardName)).To(Succeed())\n\n\tBy(\"Start manager\")\n\tmgrContext, mgrCancel := context.WithCancel(context.Background())\n\n\tgo func() {\n\t\tdefer GinkgoRecover()\n\t\tExpect(mgr.Start(mgrContext)).To(Succeed())\n\t}()\n\n\tDeferCleanup(func() {\n\t\tBy(\"Stop manager\")\n\t\tmgrCancel()\n\t})\n}, NodeTimeout(time.Minute))\n"
  },
  {
    "path": "test/integration/shard/controller/controller_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller_test\n\nimport (\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tgomegatypes \"github.com/onsi/gomega/types\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t. \"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/test/integration/shard/controller\"\n)\n\nvar obj *corev1.ConfigMap\n\nvar _ = Describe(\"Shard controller\", func() {\n\tBeforeEach(func() {\n\t\tobj = &corev1.ConfigMap{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tGenerateName: \"test-\",\n\t\t\t\tNamespace:    testRunID,\n\t\t\t\tLabels: map[string]string{\n\t\t\t\t\tshardLabel: shardName,\n\t\t\t\t\tLabelKey:   LabelValuePending,\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t}, OncePerOrdered)\n\n\tJustBeforeEach(func(ctx SpecContext) {\n\t\tExpect(testClient.Create(ctx, obj)).To(Succeed())\n\t\tlog.Info(\"Created ConfigMap for test\", \"configMapName\", obj.Name)\n\t}, NodeTimeout(time.Minute), OncePerOrdered)\n\n\tWhen(\"the object is assigned on Create event\", func() {\n\t\titShouldReconcile()\n\t\titShouldDrain()\n\n\t\tWhen(\"the predicate does not match the object\", func() {\n\t\t\tBeforeEach(ignoreObject, OncePerOrdered)\n\t\t\titShouldNotReconcile()\n\t\t\titShouldDrain()\n\t\t})\n\n\t\tWhen(\"the object should be drained on Create event\", Ordered, func() {\n\t\t\tBeforeAll(drainObject)\n\t\t\titShouldRemoveShardingLabels()\n\t\t\titShouldNotReconcile()\n\t\t})\n\t})\n\n\tWhen(\"the object is assigned to a different shard on Create event\", func() {\n\t\tBeforeEach(assignOtherShard, OncePerOrdered)\n\t\titShouldNotReconcile()\n\t\titShouldNotDrain()\n\n\t\tWhen(\"the object gets assigned\", Ordered, func() {\n\t\t\titShouldNotReconcile()\n\n\t\t\tIt(\"assign object\", func(ctx SpecContext) {\n\t\t\t\tEventually(ctx, Update(obj, assignThisShard)).Should(Succeed())\n\t\t\t}, SpecTimeout(time.Minute))\n\n\t\t\titShouldReconcile()\n\t\t})\n\t})\n})\n\nfunc itShouldReconcile() {\n\tGinkgoHelper()\n\n\tIt(\"should reconcile the object\", func(ctx SpecContext) {\n\t\tEventually(ctx, Object(obj)).Should(haveStatus(LabelValueDone))\n\t}, SpecTimeout(time.Minute))\n}\n\nfunc itShouldNotReconcile() {\n\tGinkgoHelper()\n\n\tIt(\"should not reconcile the object\", func(ctx SpecContext) {\n\t\tConsistently(ctx, Object(obj)).Should(haveStatus(obj.Labels[LabelKey]))\n\t}, SpecTimeout(time.Minute))\n}\n\nfunc itShouldDrain() {\n\tGinkgoHelper()\n\n\tDescribe(\"should handle the drain operation\", Ordered, func() {\n\t\titAddDrainLabel()\n\t\titShouldRemoveShardingLabels()\n\t\titShouldNotReconcile()\n\t})\n}\n\nfunc itShouldNotDrain() {\n\tGinkgoHelper()\n\n\tContext(\"should not handle drain operation\", Ordered, func() {\n\t\titAddDrainLabel()\n\n\t\tIt(\"should not remove shard and drain labels\", func(ctx SpecContext) {\n\t\t\tConsistently(ctx, Object(obj)).Should(And(\n\t\t\t\tHaveLabel(shardLabel),\n\t\t\t\tHaveLabel(drainLabel),\n\t\t\t))\n\t\t}, SpecTimeout(time.Minute))\n\t})\n}\n\nfunc itAddDrainLabel() {\n\tGinkgoHelper()\n\n\tIt(\"add the drain label\", func(ctx SpecContext) {\n\t\tEventually(ctx, Update(obj, drainObject)).Should(Succeed())\n\t}, SpecTimeout(time.Minute))\n}\n\nfunc itShouldRemoveShardingLabels() {\n\tGinkgoHelper()\n\n\tIt(\"should remove shard and drain labels\", func(ctx SpecContext) {\n\t\tEventually(ctx, Object(obj)).Should(And(\n\t\t\tNot(HaveLabel(shardLabel)),\n\t\t\tNot(HaveLabel(drainLabel)),\n\t\t))\n\t}, SpecTimeout(time.Minute))\n}\n\nfunc haveStatus(status string) gomegatypes.GomegaMatcher {\n\treturn HaveLabelWithValue(LabelKey, status)\n}\n\nfunc ignoreObject() {\n\tobj.Labels[LabelKey] = LabelValueIgnore\n}\n\nfunc assignThisShard() {\n\tobj.Labels[shardLabel] = shardName\n}\n\nfunc assignOtherShard() {\n\tobj.Labels[shardLabel] = \"other\"\n}\n\nfunc drainObject() {\n\tobj.Labels[drainLabel] = \"true\"\n}\n"
  },
  {
    "path": "test/integration/shard/controller/reconciler.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tcorev1 \"k8s.io/api/core/v1\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/builder\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tshardcontroller \"github.com/timebertt/kubernetes-controller-sharding/pkg/shard/controller\"\n)\n\nconst (\n\tLabelKey          = \"status\"\n\tLabelValuePending = \"pending\"\n\tLabelValueDone    = \"done\"\n\tLabelValueIgnore  = \"ignore\"\n)\n\n// Reconciler watches ConfigMaps with the `status=pending` label and sets the `status` label to `done`.\ntype Reconciler struct {\n\tClient client.Client\n}\n\n// AddToManager adds Reconciler to the given manager.\nfunc (r *Reconciler) AddToManager(mgr manager.Manager, controllerRingName, shardName string) error {\n\tif r.Client == nil {\n\t\tr.Client = mgr.GetClient()\n\t}\n\n\treturn builder.ControllerManagedBy(mgr).\n\t\tNamed(\"test\").\n\t\tFor(&corev1.ConfigMap{}, builder.WithPredicates(shardcontroller.Predicate(controllerRingName, shardName, ConfigMapPredicate()))).\n\t\tWithOptions(controller.Options{\n\t\t\tMaxConcurrentReconciles: 5,\n\t\t}).\n\t\tComplete(\n\t\t\tshardcontroller.NewShardedReconciler(mgr).\n\t\t\t\tFor(&corev1.ConfigMap{}).\n\t\t\t\tInControllerRing(controllerRingName).\n\t\t\t\tWithShardName(shardName).\n\t\t\t\tMustBuild(r),\n\t\t)\n}\n\nfunc ConfigMapPredicate() predicate.Predicate {\n\treturn predicate.NewPredicateFuncs(func(obj client.Object) bool {\n\t\treturn obj.GetLabels()[LabelKey] == LabelValuePending\n\t})\n}\n\n// Reconcile reconciles a ConfigMap.\nfunc (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {\n\tlog := logf.FromContext(ctx)\n\n\tsecret := &corev1.ConfigMap{}\n\tif err := r.Client.Get(ctx, req.NamespacedName, secret); err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\tlog.V(1).Info(\"Object is gone, stop reconciling\")\n\t\t\treturn reconcile.Result{}, nil\n\t\t}\n\t\treturn reconcile.Result{}, fmt.Errorf(\"error retrieving object from store: %w\", err)\n\t}\n\n\tlog.V(1).Info(\"Reconciling object\")\n\tpatch := client.MergeFrom(secret.DeepCopy())\n\tmetav1.SetMetaDataLabel(&secret.ObjectMeta, LabelKey, LabelValueDone)\n\treturn reconcile.Result{}, r.Client.Patch(ctx, secret, patch)\n}\n"
  },
  {
    "path": "test/integration/shard/lease/lease_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/client-go/rest\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nfunc TestController(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Shard Lease Integration Test Suite\")\n}\n\nconst testID = \"shard-lease-test\"\n\nvar (\n\tlog logr.Logger\n\n\trestConfig *rest.Config\n\n\ttestClient client.Client\n\n\ttestRunID string\n)\n\nvar _ = BeforeSuite(func(ctx SpecContext) {\n\tlogf.SetLogger(zap.New(zap.UseDevMode(true), zap.WriteTo(GinkgoWriter)))\n\tlog = logf.Log.WithName(testID)\n\n\tBy(\"Start test environment\")\n\ttestEnv := &envtest.Environment{}\n\n\tvar err error\n\trestConfig, err = testEnv.Start()\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(restConfig).NotTo(BeNil())\n\n\tDeferCleanup(func() {\n\t\tBy(\"Stop test environment\")\n\t\tExpect(testEnv.Stop()).To(Succeed())\n\t})\n\n\tBy(\"Create test clients\")\n\ttestClient, err = client.New(restConfig, client.Options{})\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(testClient).NotTo(BeNil())\n\n\tclientContext, clientCancel := context.WithCancel(context.Background())\n\tkomega.SetClient(testClient)\n\tkomega.SetContext(clientContext)\n\tDeferCleanup(clientCancel)\n\n\tBy(\"Create test Namespace\")\n\ttestNamespace := &corev1.Namespace{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tGenerateName: testID + \"-\",\n\t\t},\n\t}\n\tExpect(testClient.Create(ctx, testNamespace)).To(Succeed())\n\tlog.Info(\"Created Namespace for test\", \"namespaceName\", testNamespace.Name)\n\ttestRunID = testNamespace.Name\n\tlog = log.WithValues(\"testRunID\", testRunID)\n\n\tDeferCleanup(func(ctx SpecContext) {\n\t\tBy(\"Delete test Namespace\")\n\t\tExpect(testClient.Delete(ctx, testNamespace)).To(Or(Succeed(), BeNotFoundError()))\n\t}, NodeTimeout(time.Minute))\n}, NodeTimeout(time.Minute))\n"
  },
  {
    "path": "test/integration/shard/lease/lease_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controller_test\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/ptr\"\n\t. \"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\n\tshardlease \"github.com/timebertt/kubernetes-controller-sharding/pkg/shard/lease\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n)\n\nvar _ = Describe(\"Shard lease\", func() {\n\tvar (\n\t\tmgrOptions manager.Options\n\t\tmgrCancel  context.CancelFunc\n\n\t\tleaseOptions shardlease.Options\n\t\tlease        *coordinationv1.Lease\n\t)\n\n\tBeforeEach(func() {\n\t\tmgrOptions = manager.Options{\n\t\t\tLeaderElection:             true,\n\t\t\tLeaderElectionResourceLock: \"should-be-ignored\", // -> should use provided lock instead\n\t\t\tLeaderElectionNamespace:    \"should-be-ignored\", // -> should use provided namespace in lock instead\n\t\t\tLeaderElectionID:           \"should-be-ignored\", // -> should be shard name instead\n\n\t\t\tLeaseDuration: ptr.To(time.Second),\n\t\t\tRenewDeadline: ptr.To(100 * time.Millisecond),\n\t\t\tRetryPeriod:   ptr.To(50 * time.Millisecond),\n\t\t}\n\n\t\tleaseOptions = shardlease.Options{\n\t\t\tControllerRingName: \"test-\" + test.RandomSuffix(),\n\t\t\tLeaseNamespace:     testRunID,\n\t\t\tShardName:          \"test-\" + test.RandomSuffix(),\n\t\t}\n\n\t\tlease = &coordinationv1.Lease{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tNamespace: leaseOptions.LeaseNamespace,\n\t\t\t\tName:      leaseOptions.ShardName,\n\t\t\t},\n\t\t}\n\t}, OncePerOrdered)\n\n\tJustBeforeEach(func() {\n\t\tshardLease, err := shardlease.NewResourceLock(restConfig, leaseOptions)\n\t\tExpect(err).NotTo(HaveOccurred())\n\t\tmgrOptions.LeaderElectionResourceLockInterface = shardLease\n\n\t\tBy(\"Setup manager\")\n\t\tmgrOptions.Metrics.BindAddress = \"0\"\n\t\tmgr, err := manager.New(restConfig, mgrOptions)\n\t\tExpect(err).NotTo(HaveOccurred())\n\n\t\tBy(\"Start manager\")\n\t\tvar mgrContext context.Context\n\t\tmgrContext, mgrCancel = context.WithCancel(context.Background())\n\n\t\tmgrDone := make(chan struct{})\n\t\tgo func() {\n\t\t\tdefer GinkgoRecover()\n\t\t\tExpect(mgr.Start(mgrContext)).To(Succeed())\n\t\t\tclose(mgrDone)\n\t\t}()\n\n\t\tDeferCleanup(func(ctx SpecContext) {\n\t\t\tBy(\"Stop manager\")\n\t\t\tmgrCancel()\n\n\t\t\tBy(\"Wait for manager to stop\")\n\t\t\tEventually(ctx, mgrDone).Should(BeClosed())\n\t\t}, NodeTimeout(time.Minute))\n\t}, OncePerOrdered)\n\n\tDescribe(\"should maintain the shard lease\", Ordered, func() {\n\t\tIt(\"should create the shard lease according to the config\", func(ctx SpecContext) {\n\t\t\tEventually(ctx, Object(lease)).Should(And(\n\t\t\t\tHaveField(\"ObjectMeta.Labels\", HaveKeyWithValue(\"alpha.sharding.timebertt.dev/controllerring\", leaseOptions.ControllerRingName)),\n\t\t\t\tHaveField(\"Spec.HolderIdentity\", HaveValue(Equal(leaseOptions.ShardName))),\n\t\t\t\tHaveField(\"Spec.LeaseDurationSeconds\", HaveValue(BeEquivalentTo(1))),\n\t\t\t\tHaveField(\"Spec.AcquireTime\", Not(BeNil())),\n\t\t\t\tHaveField(\"Spec.RenewTime\", Not(BeNil())),\n\t\t\t))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"should renew the shard lease\", func(ctx SpecContext) {\n\t\t\tEventually(ctx, Object(lease)).Should(And(\n\t\t\t\tHaveField(\"Spec.HolderIdentity\", HaveValue(Equal(leaseOptions.ShardName))),\n\t\t\t\tHaveField(\"Spec.LeaseDurationSeconds\", HaveValue(BeEquivalentTo(1))),\n\t\t\t\tHaveField(\"Spec.AcquireTime.Time\", BeTemporally(\"~\", lease.Spec.AcquireTime.Time)),\n\t\t\t\tHaveField(\"Spec.RenewTime.Time\", BeTemporally(\">\", lease.Spec.RenewTime.Time)),\n\t\t\t))\n\t\t}, SpecTimeout(time.Minute))\n\t})\n\n\tDescribe(\"should renew shard lease that was acquired by sharder\", Ordered, func() {\n\t\tvar sharderAcquireTime time.Time\n\n\t\tBeforeAll(func(ctx SpecContext) {\n\t\t\tsharderAcquireTime = time.Now()\n\n\t\t\tlease.Spec.HolderIdentity = ptr.To(\"sharder\")\n\t\t\tlease.Spec.AcquireTime = ptr.To(metav1.NewMicroTime(sharderAcquireTime))\n\t\t\tlease.Spec.RenewTime = ptr.To(metav1.NewMicroTime(sharderAcquireTime))\n\t\t\tlease.Spec.LeaseDurationSeconds = ptr.To[int32](3)\n\t\t\tlease.Spec.LeaseTransitions = ptr.To[int32](1)\n\n\t\t\tEventually(ctx, func() error {\n\t\t\t\treturn testClient.Create(ctx, lease)\n\t\t\t}).Should(Succeed())\n\t\t}, NodeTimeout(time.Minute))\n\n\t\tIt(\"should wait for lease to expire\", func(ctx SpecContext) {\n\t\t\tConsistently(ctx, Object(lease)).WithTimeout(2 * time.Second).ShouldNot(\n\t\t\t\tHaveField(\"Spec.HolderIdentity\", HaveValue(Equal(leaseOptions.ShardName))),\n\t\t\t)\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"should renew the shard lease\", func(ctx SpecContext) {\n\t\t\tEventually(ctx, Object(lease)).Should(And(\n\t\t\t\tHaveField(\"Spec.HolderIdentity\", HaveValue(Equal(leaseOptions.ShardName))),\n\t\t\t\tHaveField(\"Spec.LeaseDurationSeconds\", HaveValue(BeEquivalentTo(1))),\n\t\t\t\tHaveField(\"Spec.AcquireTime.Time\", BeTemporally(\">\", sharderAcquireTime)),\n\t\t\t\tHaveField(\"Spec.RenewTime.Time\", BeTemporally(\">\", sharderAcquireTime)),\n\t\t\t\tHaveField(\"Spec.LeaseTransitions\", HaveValue(BeEquivalentTo(2))),\n\t\t\t))\n\t\t}, SpecTimeout(time.Minute))\n\t})\n\n\tWhen(\"LeaderElectionReleaseOnCancel is true\", Ordered, func() {\n\t\tBeforeAll(func() {\n\t\t\tmgrOptions.LeaderElectionReleaseOnCancel = true\n\t\t})\n\n\t\tIt(\"should create the shard lease\", func(ctx SpecContext) {\n\t\t\tEventually(ctx, Object(lease)).Should(\n\t\t\t\tHaveField(\"Spec.HolderIdentity\", HaveValue(Equal(leaseOptions.ShardName))),\n\t\t\t)\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"should release the shard lease when canceling the manager\", func(ctx SpecContext) {\n\t\t\tmgrCancel()\n\n\t\t\tEventually(ctx, Object(lease)).Should(\n\t\t\t\tHaveField(\"Spec.HolderIdentity\", HaveValue(BeEmpty())),\n\t\t\t)\n\t\t}, SpecTimeout(time.Minute))\n\t})\n})\n"
  },
  {
    "path": "test/integration/sharder/controller/controllerring/controllerring_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controllerring_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\ttestclock \"k8s.io/utils/clock/testing\"\n\t\"sigs.k8s.io/controller-runtime/pkg/cache\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\tmetricsserver \"sigs.k8s.io/controller-runtime/pkg/metrics/server\"\n\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/controller/controllerring\"\n\tutilclient \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/client\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nfunc TestControllerRing(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Sharder ControllerRing Controller Integration Test Suite\")\n}\n\nconst testID = \"controllerring-controller-test\"\n\nvar (\n\tlog logr.Logger\n\n\ttestClient client.Client\n\n\tclock *testclock.FakePassiveClock\n\n\ttestRunID     string\n\ttestRunLabels map[string]string\n)\n\nvar _ = BeforeSuite(func(ctx SpecContext) {\n\tlogf.SetLogger(zap.New(zap.UseDevMode(true), zap.WriteTo(GinkgoWriter)))\n\tlog = logf.Log.WithName(testID)\n\n\tBy(\"Start test environment\")\n\ttestEnv := &envtest.Environment{\n\t\tCRDInstallOptions: envtest.CRDInstallOptions{\n\t\t\tPaths: []string{test.PathShardingCRDs()},\n\t\t},\n\t\tErrorIfCRDPathMissing: true,\n\t}\n\n\trestConfig, err := testEnv.Start()\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(restConfig).NotTo(BeNil())\n\n\tDeferCleanup(func() {\n\t\tBy(\"Stop test environment\")\n\t\tExpect(testEnv.Stop()).To(Succeed())\n\t})\n\n\tBy(\"Create test clients\")\n\ttestClient, err = client.New(restConfig, client.Options{Scheme: utilclient.SharderScheme})\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(testClient).NotTo(BeNil())\n\n\tclientContext, clientCancel := context.WithCancel(context.Background())\n\tkomega.SetClient(testClient)\n\tkomega.SetContext(clientContext)\n\tDeferCleanup(clientCancel)\n\n\tBy(\"Create test Namespace\")\n\ttestNamespace := &corev1.Namespace{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tGenerateName: testID + \"-\",\n\t\t},\n\t}\n\tExpect(testClient.Create(ctx, testNamespace)).To(Succeed())\n\tlog.Info(\"Created Namespace for test\", \"namespaceName\", testNamespace.Name)\n\ttestRunID = testNamespace.Name\n\tlog = log.WithValues(\"testRunID\", testRunID)\n\ttestRunLabels = map[string]string{testID: testRunID}\n\n\tDeferCleanup(func(ctx SpecContext) {\n\t\tBy(\"Delete test Namespace\")\n\t\tExpect(testClient.Delete(ctx, testNamespace)).To(Or(Succeed(), BeNotFoundError()))\n\t}, NodeTimeout(time.Minute))\n\n\tBy(\"Setup manager\")\n\tmgr, err := manager.New(restConfig, manager.Options{\n\t\tScheme:  utilclient.SharderScheme,\n\t\tMetrics: metricsserver.Options{BindAddress: \"0\"},\n\t\tCache: cache.Options{\n\t\t\tDefaultNamespaces: map[string]cache.Config{testNamespace.Name: {}},\n\t\t\tByObject: map[client.Object]cache.ByObject{\n\t\t\t\t&shardingv1alpha1.ControllerRing{}: {\n\t\t\t\t\tLabel: labels.SelectorFromSet(testRunLabels),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tExpect(err).NotTo(HaveOccurred())\n\n\tBy(\"Register controller\")\n\tconfig := &configv1alpha1.SharderConfig{}\n\tmgr.GetScheme().Default(config)\n\n\tclock = testclock.NewFakePassiveClock(time.Now())\n\n\tExpect((&controllerring.Reconciler{\n\t\tClock:  clock,\n\t\tConfig: config,\n\t}).AddToManager(mgr)).To(Succeed())\n\n\tBy(\"Start manager\")\n\tmgrContext, mgrCancel := context.WithCancel(context.Background())\n\n\tgo func() {\n\t\tdefer GinkgoRecover()\n\t\tExpect(mgr.Start(mgrContext)).To(Succeed())\n\t}()\n\n\tDeferCleanup(func() {\n\t\tBy(\"Stop manager\")\n\t\tmgrCancel()\n\t})\n}, NodeTimeout(time.Minute))\n"
  },
  {
    "path": "test/integration/sharder/controller/controllerring/controllerring_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage controllerring_test\n\nimport (\n\t\"maps\"\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tgomegatypes \"github.com/onsi/gomega/types\"\n\tadmissionregistrationv1 \"k8s.io/api/admissionregistration/v1\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/ptr\"\n\t. \"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nvar _ = Describe(\"ControllerRing controller\", func() {\n\tvar (\n\t\tcontrollerRing *shardingv1alpha1.ControllerRing\n\t)\n\n\tBeforeEach(func(ctx SpecContext) {\n\t\tcontrollerRing = &shardingv1alpha1.ControllerRing{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tGenerateName: testRunID + \"-\",\n\t\t\t\tLabels:       maps.Clone(testRunLabels),\n\t\t\t},\n\t\t\tSpec: shardingv1alpha1.ControllerRingSpec{\n\t\t\t\tResources: []shardingv1alpha1.RingResource{\n\t\t\t\t\t{\n\t\t\t\t\t\tGroupResource: metav1.GroupResource{Group: \"apps\", Resource: \"deployments\"},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\n\t\tExpect(testClient.Create(ctx, controllerRing)).To(Succeed())\n\t\tlog.Info(\"Created ControllerRing for test\", \"controllerRingName\", controllerRing.Name)\n\n\t\tDeferCleanup(func(ctx SpecContext) {\n\t\t\tExpect(testClient.Delete(ctx, controllerRing)).To(Or(Succeed(), BeNotFoundError()))\n\t\t}, NodeTimeout(time.Minute))\n\t}, NodeTimeout(time.Minute), OncePerOrdered)\n\n\tIt(\"should observe the generation\", func(ctx SpecContext) {\n\t\tEventually(ctx, Object(controllerRing)).Should(\n\t\t\tHaveField(\"Status.ObservedGeneration\", Equal(controllerRing.Generation)),\n\t\t)\n\t}, SpecTimeout(time.Minute))\n\n\tIt(\"should report readiness\", func(ctx SpecContext) {\n\t\tEventually(ctx, Object(controllerRing)).Should(\n\t\t\tHaveField(\"Status.Conditions\", ConsistOf(\n\t\t\t\tMatchCondition(\n\t\t\t\t\tOfType(shardingv1alpha1.ControllerRingReady),\n\t\t\t\t\tWithStatus(metav1.ConditionTrue),\n\t\t\t\t),\n\t\t\t)),\n\t\t)\n\t}, SpecTimeout(time.Minute))\n\n\tIt(\"should apply the sharder webhook\", func(ctx SpecContext) {\n\t\twebhookConfig := &admissionregistrationv1.MutatingWebhookConfiguration{\n\t\t\tObjectMeta: metav1.ObjectMeta{Name: \"controllerring-\" + controllerRing.Name},\n\t\t}\n\t\tEventually(ctx, Object(webhookConfig)).Should(And(\n\t\t\tHaveField(\"ObjectMeta.OwnerReferences\", ConsistOf(And(\n\t\t\t\tHaveField(\"Kind\", Equal(\"ControllerRing\")),\n\t\t\t\tHaveField(\"Name\", Equal(controllerRing.Name)),\n\t\t\t))),\n\t\t\tHaveField(\"Webhooks\", ConsistOf(And(\n\t\t\t\tHaveField(\"ClientConfig.Service.Path\", HaveValue(Equal(\"/webhooks/sharder/controllerring/\"+controllerRing.Name))),\n\t\t\t\tHaveField(\"Rules\", ConsistOf(And(\n\t\t\t\t\tHaveField(\"APIGroups\", ConsistOf(\"apps\")),\n\t\t\t\t\tHaveField(\"Resources\", ConsistOf(\"deployments\")),\n\t\t\t\t))),\n\t\t\t))),\n\t\t))\n\t}, SpecTimeout(time.Minute))\n\n\tDescribe(\"should reflect the shard leases in the status\", Ordered, func() {\n\t\tvar lease *coordinationv1.Lease\n\n\t\tIt(\"create available shard lease\", func(ctx SpecContext) {\n\t\t\tlease = newLease(controllerRing.Name)\n\t\t\tExpect(testClient.Create(ctx, lease)).To(Succeed())\n\n\t\t\tEventually(ctx, Object(controllerRing)).Should(haveStatusShards(1, 1))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"create orphaned shard lease\", func(ctx SpecContext) {\n\t\t\tlease = newLease(controllerRing.Name)\n\t\t\tlease.Spec.HolderIdentity = nil\n\t\t\tExpect(testClient.Create(ctx, lease)).To(Succeed())\n\n\t\t\tEventually(ctx, Object(controllerRing)).Should(haveStatusShards(1, 2))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"make lease healthy\", func(ctx SpecContext) {\n\t\t\tEventually(ctx, Update(lease, func() {\n\t\t\t\tlease.Spec.HolderIdentity = ptr.To(lease.Name)\n\t\t\t})).Should(Succeed())\n\n\t\t\tEventually(ctx, Object(controllerRing)).Should(haveStatusShards(2, 2))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"make lease unhealthy\", func(ctx SpecContext) {\n\t\t\tEventually(ctx, Update(lease, func() {\n\t\t\t\tlease.Spec.HolderIdentity = nil\n\t\t\t})).Should(Succeed())\n\n\t\t\tEventually(ctx, Object(controllerRing)).Should(haveStatusShards(1, 2))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"delete unhealthy lease\", func(ctx SpecContext) {\n\t\t\tExpect(testClient.Delete(ctx, lease)).To(Succeed())\n\n\t\t\tEventually(ctx, Object(controllerRing)).Should(haveStatusShards(1, 1))\n\t\t}, SpecTimeout(time.Minute))\n\t})\n})\n\nfunc newLease(controllerRingName string) *coordinationv1.Lease {\n\tname := testRunID + \"-\" + test.RandomSuffix()\n\n\treturn &coordinationv1.Lease{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      name,\n\t\t\tNamespace: testRunID,\n\t\t\tLabels: map[string]string{\n\t\t\t\tshardingv1alpha1.LabelControllerRing: controllerRingName,\n\t\t\t},\n\t\t},\n\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\tHolderIdentity:       ptr.To(name),\n\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(clock.Now().Add(-5 * time.Minute))),\n\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(clock.Now().Add(-2 * time.Second))),\n\t\t},\n\t}\n}\n\nfunc haveStatusShards(availableShards, shards int32) gomegatypes.GomegaMatcher {\n\treturn And(\n\t\tHaveField(\"Status.AvailableShards\", Equal(availableShards)),\n\t\tHaveField(\"Status.Shards\", Equal(shards)),\n\t)\n}\n"
  },
  {
    "path": "test/integration/sharder/controller/sharder/sharder_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder_test\n\nimport (\n\t\"context\"\n\t\"maps\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\ttestclock \"k8s.io/utils/clock/testing\"\n\t\"sigs.k8s.io/controller-runtime/pkg/cache\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\tmetricsserver \"sigs.k8s.io/controller-runtime/pkg/metrics/server\"\n\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/controller/sharder\"\n\tutilclient \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/client\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nfunc TestSharder(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Sharder Controller Integration Test Suite\")\n}\n\nconst testID = \"sharder-controller-test\"\n\nvar (\n\tlog logr.Logger\n\n\ttestClient client.Client\n\tmgrClient  client.Client\n\n\tclock *testclock.FakePassiveClock\n\n\ttestRunID     string\n\ttestRunLabels map[string]string\n\n\tcontrollerRing *shardingv1alpha1.ControllerRing\n)\n\nvar _ = BeforeSuite(func(ctx SpecContext) {\n\tlogf.SetLogger(zap.New(zap.UseDevMode(true), zap.WriteTo(GinkgoWriter)))\n\tlog = logf.Log.WithName(testID)\n\n\tBy(\"Start test environment\")\n\ttestEnv := &envtest.Environment{\n\t\tCRDInstallOptions: envtest.CRDInstallOptions{\n\t\t\tPaths: []string{test.PathShardingCRDs()},\n\t\t},\n\t\tErrorIfCRDPathMissing: true,\n\t}\n\n\trestConfig, err := testEnv.Start()\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(restConfig).NotTo(BeNil())\n\n\tDeferCleanup(func() {\n\t\tBy(\"Stop test environment\")\n\t\tExpect(testEnv.Stop()).To(Succeed())\n\t})\n\n\tBy(\"Create test clients\")\n\ttestClient, err = client.New(restConfig, client.Options{Scheme: utilclient.SharderScheme})\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(testClient).NotTo(BeNil())\n\n\tclientContext, clientCancel := context.WithCancel(context.Background())\n\tkomega.SetClient(testClient)\n\tkomega.SetContext(clientContext)\n\tDeferCleanup(clientCancel)\n\n\tBy(\"Create test Namespace\")\n\ttestNamespace := &corev1.Namespace{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tGenerateName: testID + \"-\",\n\t\t},\n\t}\n\tExpect(testClient.Create(ctx, testNamespace)).To(Succeed())\n\tlog.Info(\"Created Namespace for test\", \"namespaceName\", testNamespace.Name)\n\ttestRunID = testNamespace.Name\n\tlog = log.WithValues(\"testRunID\", testRunID)\n\ttestRunLabels = map[string]string{testID: testRunID}\n\n\tDeferCleanup(func(ctx SpecContext) {\n\t\tBy(\"Delete test Namespace\")\n\t\tExpect(testClient.Delete(ctx, testNamespace)).To(Or(Succeed(), BeNotFoundError()))\n\t}, NodeTimeout(time.Minute))\n\n\tBy(\"Create test ControllerRing\")\n\tcontrollerRing = &shardingv1alpha1.ControllerRing{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:   testRunID,\n\t\t\tLabels: maps.Clone(testRunLabels),\n\t\t},\n\t\tSpec: shardingv1alpha1.ControllerRingSpec{\n\t\t\tResources: []shardingv1alpha1.RingResource{{\n\t\t\t\tGroupResource:       metav1.GroupResource{Group: \"\", Resource: \"secrets\"},\n\t\t\t\tControlledResources: []metav1.GroupResource{{Group: \"\", Resource: \"configmaps\"}},\n\t\t\t}},\n\t\t\tNamespaceSelector: &metav1.LabelSelector{\n\t\t\t\tMatchExpressions: []metav1.LabelSelectorRequirement{{\n\t\t\t\t\tKey:      corev1.LabelMetadataName,\n\t\t\t\t\tOperator: metav1.LabelSelectorOpIn,\n\t\t\t\t\tValues:   []string{testRunID},\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t}\n\tExpect(testClient.Create(ctx, controllerRing)).To(Succeed())\n\tlog.Info(\"Created ControllerRing for test\", \"controllerRingName\", controllerRing.Name)\n\n\tDeferCleanup(func(ctx SpecContext) {\n\t\tBy(\"Delete test ControllerRing\")\n\t\tExpect(testClient.Delete(ctx, controllerRing)).To(Or(Succeed(), BeNotFoundError()))\n\t}, NodeTimeout(time.Minute))\n\n\tBy(\"Setup manager\")\n\tmgr, err := manager.New(restConfig, manager.Options{\n\t\tScheme:  utilclient.SharderScheme,\n\t\tMetrics: metricsserver.Options{BindAddress: \"0\"},\n\t\tCache: cache.Options{\n\t\t\tDefaultNamespaces: map[string]cache.Config{\n\t\t\t\ttestNamespace.Name:      {},\n\t\t\t\tmetav1.NamespaceDefault: {},\n\t\t\t},\n\t\t\tByObject: map[client.Object]cache.ByObject{\n\t\t\t\t&shardingv1alpha1.ControllerRing{}: {\n\t\t\t\t\tLabel: labels.SelectorFromSet(testRunLabels),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tExpect(err).NotTo(HaveOccurred())\n\tmgrClient = mgr.GetClient()\n\n\tBy(\"Register controller\")\n\tconfig := &configv1alpha1.SharderConfig{}\n\tmgr.GetScheme().Default(config)\n\n\tclock = testclock.NewFakePassiveClock(time.Now())\n\n\tExpect((&sharder.Reconciler{\n\t\tClock:  clock,\n\t\tConfig: config,\n\t}).AddToManager(mgr)).To(Succeed())\n\n\tBy(\"Start manager\")\n\tmgrContext, mgrCancel := context.WithCancel(context.Background())\n\n\tgo func() {\n\t\tdefer GinkgoRecover()\n\t\tExpect(mgr.Start(mgrContext)).To(Succeed())\n\t}()\n\n\tDeferCleanup(func() {\n\t\tBy(\"Stop manager\")\n\t\tmgrCancel()\n\t})\n}, NodeTimeout(time.Minute))\n"
  },
  {
    "path": "test/integration/sharder/controller/sharder/sharder_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder_test\n\nimport (\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil\"\n\t. \"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/controller/sharder\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/key\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nvar _ = Describe(\"Sharder controller\", func() {\n\tvar (\n\t\tmainObj       *corev1.Secret\n\t\tcontrolledObj *corev1.ConfigMap\n\n\t\tavailableShard, deadShard *coordinationv1.Lease\n\t)\n\n\tBeforeEach(func(ctx SpecContext) {\n\t\tmainObj = newObject(&corev1.Secret{})\n\t\tcontrolledObj = newObject(&corev1.ConfigMap{})\n\t\t// We only test the controller in this test and not the webhook. Hence, the objects will not actually be assigned\n\t\t// after the controller triggers assignments. To verify that the sharder triggered assignments, we add the drain\n\t\t// label with an otherwise unused value. The sharder always removes the drain label when triggering assignments.\n\t\t// When triggering the drain operation, the sharder sets this label to another value.\n\t\tmetav1.SetMetaDataLabel(&mainObj.ObjectMeta, controllerRing.LabelDrain(), \"test\")\n\t\tmetav1.SetMetaDataLabel(&controlledObj.ObjectMeta, controllerRing.LabelDrain(), \"test\")\n\n\t\tavailableShard = newLease()\n\n\t\tdeadShard = newLease()\n\t\tdeadShard.Spec.HolderIdentity = nil\n\t\tExpect(testClient.Create(ctx, deadShard)).To(Succeed())\n\n\t\tDeferCleanup(func(ctx SpecContext) {\n\t\t\t// clean up all leases from this test case\n\t\t\tExpect(testClient.DeleteAllOf(ctx, &coordinationv1.Lease{}, client.InNamespace(testRunID))).To(Succeed())\n\t\t\t// wait until the manager no longer sees leases from this test case\n\t\t\tEventually(ctx, New(mgrClient).ObjectList(&coordinationv1.LeaseList{}, client.InNamespace(testRunID))).Should(HaveField(\"Items\", BeEmpty()))\n\t\t}, NodeTimeout(time.Minute))\n\t}, NodeTimeout(time.Minute))\n\n\tJustBeforeEach(func(ctx SpecContext) {\n\t\tExpect(testClient.Create(ctx, mainObj)).To(Succeed())\n\t\tExpect(controllerutil.SetControllerReference(mainObj, controlledObj, testClient.Scheme())).To(Succeed())\n\t\tExpect(testClient.Create(ctx, controlledObj)).To(Succeed())\n\t}, NodeTimeout(time.Minute))\n\n\tWhen(\"the first shard becomes available\", func() {\n\t\tJustBeforeEach(func(ctx SpecContext) {\n\t\t\tExpect(testClient.Create(ctx, availableShard)).To(Succeed())\n\t\t}, NodeTimeout(time.Minute))\n\n\t\tWhen(\"objects are not assigned\", func() {\n\t\t\tIt(\"should trigger assignments\", func(ctx SpecContext) {\n\t\t\t\tEventually(ctx, Object(mainObj)).Should(Not(HaveLabel(controllerRing.LabelDrain())))\n\t\t\t\tEventually(ctx, Object(controlledObj)).Should(Not(HaveLabel(controllerRing.LabelDrain())))\n\t\t\t}, SpecTimeout(time.Minute))\n\t\t})\n\n\t\tWhen(\"objects are assigned to unavailable shard\", func() {\n\t\t\tBeforeEach(func(ctx SpecContext) {\n\t\t\t\tmetav1.SetMetaDataLabel(&mainObj.ObjectMeta, controllerRing.LabelShard(), deadShard.Name)\n\t\t\t\tmetav1.SetMetaDataLabel(&controlledObj.ObjectMeta, controllerRing.LabelShard(), deadShard.Name)\n\t\t\t}, NodeTimeout(time.Minute))\n\n\t\t\tIt(\"should trigger assignments\", func(ctx SpecContext) {\n\t\t\t\tEventually(ctx, Object(mainObj)).Should(And(\n\t\t\t\t\tNot(HaveLabel(controllerRing.LabelShard())),\n\t\t\t\t\tNot(HaveLabel(controllerRing.LabelDrain())),\n\t\t\t\t))\n\t\t\t\tEventually(ctx, Object(controlledObj)).Should(And(\n\t\t\t\t\tNot(HaveLabel(controllerRing.LabelShard())),\n\t\t\t\t\tNot(HaveLabel(controllerRing.LabelDrain())),\n\t\t\t\t))\n\t\t\t}, SpecTimeout(time.Minute))\n\t\t})\n\n\t\tWhen(\"objects are not in a selected namespace\", func() {\n\t\t\tBeforeEach(func() {\n\t\t\t\tmainObj.Namespace = metav1.NamespaceDefault\n\t\t\t\tcontrolledObj.Namespace = metav1.NamespaceDefault\n\t\t\t})\n\n\t\t\tIt(\"should not trigger assignments\", func(ctx SpecContext) {\n\t\t\t\tConsistently(ctx, Object(mainObj)).Should(HaveLabelWithValue(controllerRing.LabelDrain(), \"test\"))\n\t\t\t\tConsistently(ctx, Object(controlledObj)).Should(HaveLabelWithValue(controllerRing.LabelDrain(), \"test\"))\n\t\t\t}, SpecTimeout(time.Minute))\n\t\t})\n\n\t\tWhen(\"controlled object doesn't have a controller reference\", func() {\n\t\t\tvar uncontrolledObj *corev1.ConfigMap\n\n\t\t\tBeforeEach(func(ctx SpecContext) {\n\t\t\t\tuncontrolledObj = newObject(&corev1.ConfigMap{})\n\t\t\t\tmetav1.SetMetaDataLabel(&uncontrolledObj.ObjectMeta, controllerRing.LabelDrain(), \"test\")\n\t\t\t\tExpect(testClient.Create(ctx, uncontrolledObj)).To(Succeed())\n\t\t\t}, NodeTimeout(time.Minute))\n\n\t\t\tIt(\"should not trigger assignments\", func(ctx SpecContext) {\n\t\t\t\tEventually(ctx, Object(controlledObj)).Should(Not(HaveLabel(controllerRing.LabelDrain())))\n\t\t\t\tConsistently(ctx, Object(uncontrolledObj)).Should(HaveLabelWithValue(controllerRing.LabelDrain(), \"test\"))\n\t\t\t}, SpecTimeout(time.Minute))\n\t\t})\n\t})\n\n\tWhen(\"the assigned shard becomes unavailable\", func() {\n\t\tvar newShard *coordinationv1.Lease\n\n\t\tBeforeEach(func() {\n\t\t\tmetav1.SetMetaDataLabel(&mainObj.ObjectMeta, controllerRing.LabelShard(), availableShard.Name)\n\t\t\tmetav1.SetMetaDataLabel(&controlledObj.ObjectMeta, controllerRing.LabelShard(), availableShard.Name)\n\n\t\t\tnewShard = newLease()\n\n\t\t\t// overwrite key functions to prefer first shard\n\t\t\tDeferCleanup(overwriteKeyFuncs(keyForShard(availableShard.Name)))\n\t\t})\n\n\t\tJustBeforeEach(func(ctx SpecContext) {\n\t\t\tExpect(testClient.Create(ctx, availableShard)).To(Succeed())\n\t\t\tExpect(testClient.Create(ctx, newShard)).To(Succeed())\n\t\t}, NodeTimeout(time.Minute))\n\n\t\tIt(\"should immediately move the objects\", func(ctx SpecContext) {\n\t\t\tBy(\"assigned shard is still available\")\n\t\t\tConsistently(ctx, Object(mainObj)).Should(HaveLabelWithValue(controllerRing.LabelShard(), availableShard.Name))\n\t\t\tConsistently(ctx, Object(controlledObj)).Should(HaveLabelWithValue(controllerRing.LabelShard(), availableShard.Name))\n\n\t\t\tBy(\"assigned shard becomes unavailable\")\n\t\t\tEventually(ctx, Update(availableShard, func() {\n\t\t\t\tavailableShard.Spec.HolderIdentity = nil\n\t\t\t})).Should(Succeed())\n\n\t\t\tEventually(ctx, Object(mainObj)).Should(And(\n\t\t\t\tNot(HaveLabel(controllerRing.LabelShard())),\n\t\t\t\tNot(HaveLabel(controllerRing.LabelDrain())),\n\t\t\t))\n\t\t\tEventually(ctx, Object(controlledObj)).Should(And(\n\t\t\t\tNot(HaveLabel(controllerRing.LabelShard())),\n\t\t\t\tNot(HaveLabel(controllerRing.LabelDrain())),\n\t\t\t))\n\t\t}, SpecTimeout(time.Minute))\n\t})\n\n\tWhen(\"another shard becomes available\", func() {\n\t\tvar newShard *coordinationv1.Lease\n\n\t\tBeforeEach(func() {\n\t\t\tmetav1.SetMetaDataLabel(&mainObj.ObjectMeta, controllerRing.LabelShard(), availableShard.Name)\n\t\t\tmetav1.SetMetaDataLabel(&controlledObj.ObjectMeta, controllerRing.LabelShard(), availableShard.Name)\n\n\t\t\tnewShard = newLease()\n\t\t\tnewShard.Spec.HolderIdentity = nil\n\n\t\t\t// overwrite key functions to prefer new shard\n\t\t\tDeferCleanup(overwriteKeyFuncs(keyForShard(newShard.Name)))\n\t\t})\n\n\t\tJustBeforeEach(func(ctx SpecContext) {\n\t\t\tExpect(testClient.Create(ctx, availableShard)).To(Succeed())\n\t\t\tExpect(testClient.Create(ctx, newShard)).To(Succeed())\n\t\t}, NodeTimeout(time.Minute))\n\n\t\tIt(\"should drain the main object and immediately move the controlled object\", func(ctx SpecContext) {\n\t\t\tBy(\"only one shard is available\")\n\t\t\tConsistently(ctx, Object(mainObj)).Should(HaveLabelWithValue(controllerRing.LabelShard(), availableShard.Name))\n\t\t\tConsistently(ctx, Object(controlledObj)).Should(HaveLabelWithValue(controllerRing.LabelShard(), availableShard.Name))\n\n\t\t\tBy(\"a new shard becomes available\")\n\t\t\tEventually(ctx, Update(newShard, func() {\n\t\t\t\tnewShard.Spec.HolderIdentity = ptr.To(newShard.Name)\n\t\t\t})).Should(Succeed())\n\n\t\t\tEventually(ctx, Object(mainObj)).Should(And(\n\t\t\t\tHaveLabelWithValue(controllerRing.LabelShard(), availableShard.Name),\n\t\t\t\tHaveLabel(controllerRing.LabelDrain()),\n\t\t\t), \"should drain the main object\")\n\t\t\tEventually(ctx, Object(controlledObj)).Should(And(\n\t\t\t\tNot(HaveLabel(controllerRing.LabelShard())),\n\t\t\t\tNot(HaveLabel(controllerRing.LabelDrain())),\n\t\t\t), \"should move the controlled object\")\n\t\t}, SpecTimeout(time.Minute))\n\t})\n})\n\nfunc newObject[T client.Object](obj T) T {\n\tobj.SetName(testRunID + \"-\" + test.RandomSuffix())\n\tobj.SetNamespace(testRunID)\n\treturn obj\n}\n\nfunc newLease() *coordinationv1.Lease {\n\tname := testRunID + \"-\" + test.RandomSuffix()\n\n\treturn &coordinationv1.Lease{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      name,\n\t\t\tNamespace: testRunID,\n\t\t\tLabels: map[string]string{\n\t\t\t\tshardingv1alpha1.LabelControllerRing: controllerRing.Name,\n\t\t\t},\n\t\t},\n\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\tHolderIdentity:       ptr.To(name),\n\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(clock.Now().Add(-5 * time.Minute))),\n\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(clock.Now().Add(-2 * time.Second))),\n\t\t},\n\t}\n}\n\nfunc overwriteKeyFuncs(fn key.Func) func() {\n\torigObject, origController := sharder.KeyForObject, sharder.KeyForController\n\tsharder.KeyForObject, sharder.KeyForController = fn, fn\n\n\treturn func() {\n\t\tsharder.KeyForObject, sharder.KeyForController = origObject, origController\n\t}\n}\n\n// keyForShard returns a key.Func that prefers assigning all objects to the shard with the given name.\n// This is done by returning the key used for the first virtual node of the shard.\nfunc keyForShard(shardName string) key.Func {\n\treturn func(obj client.Object) (string, error) {\n\t\treturn shardName + \"0\", nil\n\t}\n}\n"
  },
  {
    "path": "test/integration/sharder/controller/shardlease/shardlease_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage shardlease_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\ttestclock \"k8s.io/utils/clock/testing\"\n\t\"sigs.k8s.io/controller-runtime/pkg/cache\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\tmetricsserver \"sigs.k8s.io/controller-runtime/pkg/metrics/server\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/controller/shardlease\"\n\tutilclient \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/client\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nfunc TestShardLease(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Sharder Shard Lease Controller Integration Test Suite\")\n}\n\nconst testID = \"shardlease-controller-test\"\n\nvar (\n\tlog logr.Logger\n\n\ttestClient client.Client\n\n\tclock *testclock.FakeClock\n\n\ttestRunID     string\n\ttestRunLabels map[string]string\n)\n\nvar _ = BeforeSuite(func(ctx SpecContext) {\n\tlogf.SetLogger(zap.New(zap.UseDevMode(true), zap.WriteTo(GinkgoWriter)))\n\tlog = logf.Log.WithName(testID)\n\n\tBy(\"Start test environment\")\n\ttestEnv := &envtest.Environment{\n\t\tCRDInstallOptions: envtest.CRDInstallOptions{\n\t\t\tPaths: []string{test.PathShardingCRDs()},\n\t\t},\n\t\tErrorIfCRDPathMissing: true,\n\t}\n\n\trestConfig, err := testEnv.Start()\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(restConfig).NotTo(BeNil())\n\n\tDeferCleanup(func() {\n\t\tBy(\"Stop test environment\")\n\t\tExpect(testEnv.Stop()).To(Succeed())\n\t})\n\n\tBy(\"Create test clients\")\n\ttestClient, err = client.New(restConfig, client.Options{Scheme: utilclient.SharderScheme})\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(testClient).NotTo(BeNil())\n\n\tclientContext, clientCancel := context.WithCancel(context.Background())\n\tkomega.SetClient(testClient)\n\tkomega.SetContext(clientContext)\n\tDeferCleanup(clientCancel)\n\n\tBy(\"Create test Namespace\")\n\ttestNamespace := &corev1.Namespace{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tGenerateName: testID + \"-\",\n\t\t},\n\t}\n\tExpect(testClient.Create(ctx, testNamespace)).To(Succeed())\n\tlog.Info(\"Created Namespace for test\", \"namespaceName\", testNamespace.Name)\n\ttestRunID = testNamespace.Name\n\tlog = log.WithValues(\"testRunID\", testRunID)\n\ttestRunLabels = map[string]string{testID: testRunID}\n\n\tDeferCleanup(func(ctx SpecContext) {\n\t\tBy(\"Delete test Namespace\")\n\t\tExpect(testClient.Delete(ctx, testNamespace)).To(Or(Succeed(), BeNotFoundError()))\n\t}, NodeTimeout(time.Minute))\n\n\tBy(\"Setup manager\")\n\tmgr, err := manager.New(restConfig, manager.Options{\n\t\tScheme:  utilclient.SharderScheme,\n\t\tMetrics: metricsserver.Options{BindAddress: \"0\"},\n\t\tCache: cache.Options{\n\t\t\tDefaultNamespaces: map[string]cache.Config{testNamespace.Name: {}},\n\t\t\tByObject: map[client.Object]cache.ByObject{\n\t\t\t\t&shardingv1alpha1.ControllerRing{}: {\n\t\t\t\t\tLabel: labels.SelectorFromSet(testRunLabels),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tExpect(err).NotTo(HaveOccurred())\n\n\tBy(\"Register controller\")\n\tclock = testclock.NewFakeClock(time.Now())\n\n\tExpect((&shardlease.Reconciler{\n\t\tClock: clock,\n\t}).AddToManager(mgr)).To(Succeed())\n\n\tBy(\"Start manager\")\n\tmgrContext, mgrCancel := context.WithCancel(context.Background())\n\n\tgo func() {\n\t\tdefer GinkgoRecover()\n\t\tExpect(mgr.Start(mgrContext)).To(Succeed())\n\t}()\n\n\tDeferCleanup(func() {\n\t\tBy(\"Stop manager\")\n\t\tmgrCancel()\n\t})\n}, NodeTimeout(time.Minute))\n"
  },
  {
    "path": "test/integration/sharder/controller/shardlease/shardlease_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage shardlease_test\n\nimport (\n\t\"maps\"\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tgomegatypes \"github.com/onsi/gomega/types\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/utils/ptr\"\n\t. \"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nvar _ = Describe(\"Shard Lease controller\", func() {\n\tvar (\n\t\tcontrollerRing *shardingv1alpha1.ControllerRing\n\t\tlease          *coordinationv1.Lease\n\t)\n\n\tBeforeEach(func(ctx SpecContext) {\n\t\tcontrollerRing = &shardingv1alpha1.ControllerRing{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tGenerateName: testRunID + \"-\",\n\t\t\t\tLabels:       maps.Clone(testRunLabels),\n\t\t\t},\n\t\t\tSpec: shardingv1alpha1.ControllerRingSpec{\n\t\t\t\tResources: []shardingv1alpha1.RingResource{\n\t\t\t\t\t{\n\t\t\t\t\t\tGroupResource: metav1.GroupResource{Group: \"apps\", Resource: \"deployments\"},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\n\t\tExpect(testClient.Create(ctx, controllerRing)).To(Succeed())\n\t\tlog.Info(\"Created ControllerRing for test\", \"controllerRingName\", controllerRing.Name)\n\n\t\tDeferCleanup(func(ctx SpecContext) {\n\t\t\tExpect(testClient.Delete(ctx, controllerRing)).To(Or(Succeed(), BeNotFoundError()))\n\t\t}, NodeTimeout(time.Minute))\n\n\t\tname := testRunID + \"-\" + test.RandomSuffix()\n\t\tlease = &coordinationv1.Lease{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tName:      name,\n\t\t\t\tNamespace: testRunID,\n\t\t\t\tLabels: map[string]string{\n\t\t\t\t\tshardingv1alpha1.LabelControllerRing: controllerRing.Name,\n\t\t\t\t},\n\t\t\t},\n\t\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\t\tHolderIdentity:       ptr.To(name),\n\t\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(clock.Now().Add(-5 * time.Minute))),\n\t\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(clock.Now().Add(-2 * time.Second))),\n\t\t\t},\n\t\t}\n\n\t\tExpect(testClient.Create(ctx, lease)).To(Succeed())\n\t\tlog.Info(\"Created Lease for test\", \"leaseName\", lease.Name)\n\t}, NodeTimeout(time.Minute), OncePerOrdered)\n\n\tDescribe(\"should reflect the shard state in the label\", Ordered, func() {\n\t\tIt(\"shard is ready\", func(ctx SpecContext) {\n\t\t\tEventually(ctx, Object(lease)).Should(haveState(\"ready\"))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"lease is expired\", func(ctx SpecContext) {\n\t\t\tclock.Step(8 * time.Second)\n\t\t\tEventually(ctx, Object(lease)).Should(haveState(\"expired\"))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"expired lease is renewed\", func(ctx SpecContext) {\n\t\t\tclock.Step(8 * time.Second)\n\t\t\tEventually(ctx, Object(lease)).Should(haveState(\"expired\"))\n\n\t\t\tEventually(ctx, Update(lease, func() {\n\t\t\t\tlease.Spec.RenewTime = ptr.To(metav1.NewMicroTime(clock.Now()))\n\t\t\t})).Should(Succeed())\n\t\t\tEventually(ctx, Object(lease)).Should(haveState(\"ready\"))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"should acquire expired lease that is not renewed\", func(ctx SpecContext) {\n\t\t\tclock.Step(10 * time.Second)\n\t\t\tEventually(ctx, Object(lease)).Should(haveState(\"expired\"))\n\n\t\t\tclock.Step(10 * time.Second)\n\t\t\tEventually(ctx, Object(lease)).Should(And(\n\t\t\t\thaveState(\"dead\"),\n\t\t\t\tHaveField(\"Spec.HolderIdentity\", HaveValue(Equal(\"shardlease-controller\"))),\n\t\t\t\tHaveField(\"Spec.LeaseDurationSeconds\", HaveValue(BeEquivalentTo(20))),\n\t\t\t\tHaveField(\"Spec.AcquireTime.Time\", BeTemporally(\"~\", clock.Now())),\n\t\t\t\tHaveField(\"Spec.RenewTime.Time\", BeTemporally(\"~\", clock.Now())),\n\t\t\t\tHaveField(\"Spec.LeaseTransitions\", HaveValue(BeEquivalentTo(1))),\n\t\t\t))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"dead lease is renewed\", func(ctx SpecContext) {\n\t\t\tEventually(ctx, Update(lease, func() {\n\t\t\t\tlease.Spec.HolderIdentity = ptr.To(lease.Name)\n\t\t\t\tlease.Spec.LeaseDurationSeconds = ptr.To[int32](10)\n\t\t\t\tlease.Spec.AcquireTime = ptr.To(metav1.NewMicroTime(clock.Now()))\n\t\t\t\tlease.Spec.RenewTime = ptr.To(metav1.NewMicroTime(clock.Now()))\n\t\t\t\t*lease.Spec.LeaseTransitions++\n\t\t\t})).Should(Succeed())\n\t\t\tEventually(ctx, Object(lease)).Should(haveState(\"ready\"))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"should garbage collect orphaned leases\", func(ctx SpecContext) {\n\t\t\tclock.Step(20 * time.Second)\n\t\t\tEventually(ctx, Object(lease)).Should(haveState(\"dead\"))\n\n\t\t\tclock.Step(20*time.Second + time.Minute)\n\t\t\tEventually(ctx, Get(lease)).Should(BeNotFoundError())\n\t\t}, SpecTimeout(time.Minute))\n\t})\n})\n\nfunc haveState(state string) gomegatypes.GomegaMatcher {\n\treturn HaveLabelWithValue(\"alpha.sharding.timebertt.dev/state\", state)\n}\n"
  },
  {
    "path": "test/integration/sharder/webhook/sharder/sharder_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder_test\n\nimport (\n\t\"context\"\n\t\"maps\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tadmissionregistrationv1 \"k8s.io/api/admissionregistration/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\ttestclock \"k8s.io/utils/clock/testing\"\n\t\"sigs.k8s.io/controller-runtime/pkg/cache\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\tmetricsserver \"sigs.k8s.io/controller-runtime/pkg/metrics/server\"\n\t\"sigs.k8s.io/controller-runtime/pkg/webhook\"\n\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/config/v1alpha1\"\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/controller/controllerring\"\n\tutilclient \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/client\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/webhook/sharder\"\n)\n\nfunc TestSharder(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Sharder Webhook Integration Test Suite\")\n}\n\nconst testID = \"sharder-webhook-test\"\n\nvar (\n\tlog logr.Logger\n\n\ttestClient client.Client\n\tmgrClient  client.Client\n\n\tclock *testclock.FakeClock\n\n\ttestRunID     string\n\ttestRunLabels map[string]string\n\n\tcontrollerRing *shardingv1alpha1.ControllerRing\n)\n\nvar _ = BeforeSuite(func(ctx SpecContext) {\n\tlogf.SetLogger(zap.New(zap.UseDevMode(true), zap.WriteTo(GinkgoWriter)))\n\tlog = logf.Log.WithName(testID)\n\n\ttestRunID = testID + \"-\" + test.RandomSuffix()\n\ttestRunLabels = map[string]string{testID: testRunID}\n\n\tcontrollerRing = &shardingv1alpha1.ControllerRing{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:   testRunID,\n\t\t\tLabels: maps.Clone(testRunLabels),\n\t\t},\n\t\tSpec: shardingv1alpha1.ControllerRingSpec{\n\t\t\tResources: []shardingv1alpha1.RingResource{{\n\t\t\t\tGroupResource:       metav1.GroupResource{Group: \"\", Resource: \"configmaps\"},\n\t\t\t\tControlledResources: []metav1.GroupResource{{Group: \"\", Resource: \"secrets\"}},\n\t\t\t}},\n\t\t},\n\t}\n\n\twebhookConfig := controllerring.WebhookConfigForControllerRing(controllerRing, &configv1alpha1.WebhookConfig{\n\t\tClientConfig: &admissionregistrationv1.WebhookClientConfig{\n\t\t\t// the path will be set by the called function, and envtest will transform it to the proper URL\n\t\t\tService: &admissionregistrationv1.ServiceReference{},\n\t\t},\n\t\tNamespaceSelector: &metav1.LabelSelector{\n\t\t\tMatchExpressions: []metav1.LabelSelectorRequirement{{\n\t\t\t\tKey:      corev1.LabelMetadataName,\n\t\t\t\tOperator: metav1.LabelSelectorOpIn,\n\t\t\t\tValues:   []string{testRunID},\n\t\t\t}},\n\t\t},\n\t})\n\n\tBy(\"Start test environment\")\n\ttestEnv := &envtest.Environment{\n\t\tCRDInstallOptions: envtest.CRDInstallOptions{\n\t\t\tPaths: []string{test.PathShardingCRDs()},\n\t\t},\n\t\tErrorIfCRDPathMissing: true,\n\t\tWebhookInstallOptions: envtest.WebhookInstallOptions{\n\t\t\tMutatingWebhooks: []*admissionregistrationv1.MutatingWebhookConfiguration{webhookConfig},\n\t\t},\n\t}\n\n\tif test.UseExistingCluster() {\n\t\t// NB: envtest does a lookup and complains if it cannot resolve this host. Add a dummy entry to /etc/host as a\n\t\t// workaround.\n\t\ttestEnv.WebhookInstallOptions.LocalServingHostExternalName = \"host.docker.internal\"\n\n\t\tDeferCleanup(func(ctx SpecContext) {\n\t\t\tExpect(testClient.Delete(ctx, webhookConfig)).To(Succeed())\n\t\t}, NodeTimeout(time.Minute))\n\t}\n\n\trestConfig, err := testEnv.Start()\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(restConfig).NotTo(BeNil())\n\n\tDeferCleanup(func() {\n\t\tBy(\"Stop test environment\")\n\t\tExpect(testEnv.Stop()).To(Succeed())\n\t})\n\n\tBy(\"Create test clients\")\n\ttestClient, err = client.New(restConfig, client.Options{Scheme: utilclient.SharderScheme})\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(testClient).NotTo(BeNil())\n\n\tclientContext, clientCancel := context.WithCancel(context.Background())\n\tkomega.SetClient(testClient)\n\tkomega.SetContext(clientContext)\n\tDeferCleanup(clientCancel)\n\n\tBy(\"Create test Namespace\")\n\ttestNamespace := &corev1.Namespace{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName: testRunID,\n\t\t},\n\t}\n\tExpect(testClient.Create(ctx, testNamespace)).To(Succeed())\n\tlog.Info(\"Created Namespace for test\", \"namespaceName\", testNamespace.Name)\n\tlog = log.WithValues(\"testRunID\", testRunID)\n\n\tDeferCleanup(func(ctx SpecContext) {\n\t\tBy(\"Delete test Namespace\")\n\t\tExpect(testClient.Delete(ctx, testNamespace)).To(Or(Succeed(), BeNotFoundError()))\n\t}, NodeTimeout(time.Minute))\n\n\tBy(\"Create ControllerRing\")\n\tExpect(testClient.Create(ctx, controllerRing)).To(Succeed())\n\tlog.Info(\"Created ControllerRing for test\", \"controllerRingName\", controllerRing.Name)\n\n\tDeferCleanup(func(ctx SpecContext) {\n\t\tExpect(testClient.Delete(ctx, controllerRing)).To(Or(Succeed(), BeNotFoundError()))\n\t}, NodeTimeout(time.Minute))\n\n\tBy(\"Setup manager\")\n\tmgr, err := manager.New(restConfig, manager.Options{\n\t\tScheme:  utilclient.SharderScheme,\n\t\tMetrics: metricsserver.Options{BindAddress: \"0\"},\n\t\tWebhookServer: webhook.NewServer(webhook.Options{\n\t\t\tPort:    testEnv.WebhookInstallOptions.LocalServingPort,\n\t\t\tHost:    testEnv.WebhookInstallOptions.LocalServingHost,\n\t\t\tCertDir: testEnv.WebhookInstallOptions.LocalServingCertDir,\n\t\t}),\n\t\tCache: cache.Options{\n\t\t\tDefaultNamespaces: map[string]cache.Config{testNamespace.Name: {}},\n\t\t\tByObject: map[client.Object]cache.ByObject{\n\t\t\t\t&shardingv1alpha1.ControllerRing{}: {\n\t\t\t\t\tLabel: labels.SelectorFromSet(testRunLabels),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tExpect(err).NotTo(HaveOccurred())\n\tmgrClient = mgr.GetClient()\n\n\tBy(\"Register webhook\")\n\tclock = testclock.NewFakeClock(time.Now())\n\n\tExpect((&sharder.Handler{\n\t\tClock: clock,\n\t}).AddToManager(mgr)).To(Succeed())\n\n\tBy(\"Start manager\")\n\tmgrContext, mgrCancel := context.WithCancel(context.Background())\n\n\tgo func() {\n\t\tdefer GinkgoRecover()\n\t\tExpect(mgr.Start(mgrContext)).To(Succeed())\n\t}()\n\n\tDeferCleanup(func() {\n\t\tBy(\"Stop manager\")\n\t\tmgrCancel()\n\t})\n}, NodeTimeout(time.Minute))\n"
  },
  {
    "path": "test/integration/sharder/webhook/sharder/sharder_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage sharder_test\n\nimport (\n\t\"context\"\n\t\"maps\"\n\t\"time\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tgomegatypes \"github.com/onsi/gomega/types\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil\"\n\t. \"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n)\n\nvar _ = Describe(\"Shard Lease controller\", func() {\n\tvar (\n\t\tmainObj *corev1.ConfigMap\n\n\t\tavailableShard, deadShard *coordinationv1.Lease\n\t)\n\n\tBeforeEach(func(ctx SpecContext) {\n\t\tmainObj = &corev1.ConfigMap{\n\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\tName:      \"test-\" + test.RandomSuffix(),\n\t\t\t\tNamespace: testRunID,\n\t\t\t\tLabels:    maps.Clone(testRunLabels),\n\t\t\t},\n\t\t}\n\n\t\tavailableShard = newLease()\n\t\tExpect(testClient.Create(ctx, availableShard)).To(Succeed())\n\n\t\tdeadShard = newLease()\n\t\tdeadShard.Spec.HolderIdentity = nil\n\t\tExpect(testClient.Create(ctx, deadShard)).To(Succeed())\n\n\t\tDeferCleanup(func(ctx SpecContext) {\n\t\t\t// clean up all leases from this test case\n\t\t\tExpect(testClient.DeleteAllOf(ctx, &coordinationv1.Lease{}, client.InNamespace(testRunID))).To(Succeed())\n\t\t\t// wait until the manager no longer sees leases from this test case\n\t\t\tEventually(ctx, New(mgrClient).ObjectList(&coordinationv1.LeaseList{}, client.InNamespace(testRunID))).Should(HaveField(\"Items\", BeEmpty()))\n\t\t}, NodeTimeout(time.Minute))\n\t}, NodeTimeout(time.Minute))\n\n\tDescribe(\"main resource\", func() {\n\t\tIt(\"should assign the object during creation\", func(ctx SpecContext) {\n\t\t\tEventually(ctx, createObject(mainObj)).Should(beAssigned(availableShard.Name))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"should fail due to unsupported generateName\", func(ctx SpecContext) {\n\t\t\tmainObj.Name = \"\"\n\t\t\tmainObj.GenerateName = \"test-\"\n\n\t\t\tEventually(ctx, func(ctx context.Context) error {\n\t\t\t\treturn testClient.Create(ctx, mainObj, client.DryRunAll)\n\t\t\t}).Should(MatchError(ContainSubstring(\"generateName is not supported\")))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tWhen(\"the assigned shard gets unavailable\", func() {\n\t\t\tvar (\n\t\t\t\tassignedShard, otherShard *coordinationv1.Lease\n\t\t\t)\n\n\t\t\tBeforeEach(func(ctx SpecContext) {\n\t\t\t\tEventually(ctx, createObject(mainObj)).Should(beAssigned(availableShard.Name))\n\n\t\t\t\tEventually(ctx, Update(availableShard, func() {\n\t\t\t\t\tavailableShard.Spec.HolderIdentity = nil\n\t\t\t\t})).Should(Succeed())\n\t\t\t\tassignedShard = availableShard\n\n\t\t\t\tEventually(ctx, Update(deadShard, func() {\n\t\t\t\t\tdeadShard.Spec.HolderIdentity = ptr.To(deadShard.Name)\n\t\t\t\t})).Should(Succeed())\n\t\t\t\totherShard = deadShard\n\t\t\t}, NodeTimeout(time.Minute))\n\n\t\t\tIt(\"should not reassign the object during update\", func(ctx SpecContext) {\n\t\t\t\tConsistently(ctx, patchObject(mainObj)).Should(beAssigned(assignedShard.Name))\n\t\t\t})\n\n\t\t\tIt(\"should reassign the object during drain\", func(ctx SpecContext) {\n\t\t\t\tEventually(ctx, drainObject(mainObj)).Should(beAssigned(otherShard.Name))\n\t\t\t})\n\t\t})\n\t})\n\n\tDescribe(\"controlled resource\", func() {\n\t\tvar controlledObj *corev1.Secret\n\n\t\tBeforeEach(func(ctx SpecContext) {\n\t\t\tEventually(ctx, createObject(mainObj)).Should(beAssigned(availableShard.Name))\n\n\t\t\tcontrolledObj = &corev1.Secret{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName:      \"test-\" + test.RandomSuffix(),\n\t\t\t\t\tNamespace: testRunID,\n\t\t\t\t\tLabels:    maps.Clone(testRunLabels),\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tExpect(controllerutil.SetControllerReference(mainObj, controlledObj, testClient.Scheme())).To(Succeed())\n\t\t}, NodeTimeout(time.Minute))\n\n\t\tIt(\"should assign the object during creation\", func(ctx SpecContext) {\n\t\t\tEventually(ctx, createObject(controlledObj)).Should(beAssigned(availableShard.Name))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"should assign the object during creation with generateName\", func(ctx SpecContext) {\n\t\t\tcontrolledObj.Name = \"\"\n\t\t\tcontrolledObj.GenerateName = \"test-\"\n\n\t\t\tEventually(ctx, createObject(controlledObj)).Should(beAssigned(availableShard.Name))\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tIt(\"should not assign an object without controller reference\", func(ctx SpecContext) {\n\t\t\tcontrolledObj.OwnerReferences = nil\n\n\t\t\tConsistently(ctx, createObject(controlledObj, client.DryRunAll)).ShouldNot(beAssigned())\n\t\t}, SpecTimeout(time.Minute))\n\n\t\tWhen(\"the assigned shard gets unavailable\", func() {\n\t\t\tvar (\n\t\t\t\tassignedShard, otherShard *coordinationv1.Lease\n\t\t\t)\n\n\t\t\tBeforeEach(func(ctx SpecContext) {\n\t\t\t\tEventually(ctx, createObject(controlledObj)).Should(beAssigned(availableShard.Name))\n\n\t\t\t\tEventually(ctx, Update(availableShard, func() {\n\t\t\t\t\tavailableShard.Spec.HolderIdentity = nil\n\t\t\t\t})).Should(Succeed())\n\t\t\t\tassignedShard = availableShard\n\n\t\t\t\tEventually(ctx, Update(deadShard, func() {\n\t\t\t\t\tdeadShard.Spec.HolderIdentity = ptr.To(deadShard.Name)\n\t\t\t\t})).Should(Succeed())\n\t\t\t\totherShard = deadShard\n\t\t\t}, NodeTimeout(time.Minute))\n\n\t\t\tIt(\"should not reassign the object during update\", func(ctx SpecContext) {\n\t\t\t\tConsistently(ctx, patchObject(controlledObj)).Should(beAssigned(assignedShard.Name))\n\t\t\t})\n\n\t\t\tIt(\"should reassign the object during drain\", func(ctx SpecContext) {\n\t\t\t\tEventually(ctx, drainObject(controlledObj)).Should(beAssigned(otherShard.Name))\n\t\t\t})\n\t\t})\n\t})\n})\n\nfunc newLease() *coordinationv1.Lease {\n\tname := testRunID + \"-\" + test.RandomSuffix()\n\n\treturn &coordinationv1.Lease{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      name,\n\t\t\tNamespace: testRunID,\n\t\t\tLabels: map[string]string{\n\t\t\t\tshardingv1alpha1.LabelControllerRing: controllerRing.Name,\n\t\t\t},\n\t\t},\n\t\tSpec: coordinationv1.LeaseSpec{\n\t\t\tHolderIdentity:       ptr.To(name),\n\t\t\tLeaseDurationSeconds: ptr.To[int32](10),\n\t\t\tAcquireTime:          ptr.To(metav1.NewMicroTime(clock.Now().Add(-5 * time.Minute))),\n\t\t\tRenewTime:            ptr.To(metav1.NewMicroTime(clock.Now().Add(-2 * time.Second))),\n\t\t},\n\t}\n}\n\nfunc beAssigned(shard ...string) gomegatypes.GomegaMatcher {\n\tif len(shard) == 0 {\n\t\treturn HaveLabel(\"shard.alpha.sharding.timebertt.dev/\" + controllerRing.Name)\n\t}\n\n\treturn HaveLabelWithValue(\"shard.alpha.sharding.timebertt.dev/\"+controllerRing.Name, shard[0])\n}\n\nfunc createObject(obj client.Object, opts ...client.CreateOption) func(ctx context.Context) (client.Object, error) {\n\treturn func(ctx context.Context) (client.Object, error) {\n\t\tobj.SetResourceVersion(\"\")\n\n\t\terr := testClient.Create(ctx, obj, opts...)\n\t\tif apierrors.IsAlreadyExists(err) {\n\t\t\treturn obj, StopTrying(err.Error())\n\t\t}\n\n\t\treturn obj, err\n\t}\n}\n\nfunc patchObject(obj client.Object) func(ctx context.Context) (client.Object, error) {\n\treturn func(ctx context.Context) (client.Object, error) {\n\t\treturn obj, testClient.Patch(ctx, obj, client.RawPatch(types.MergePatchType, []byte(\"{}\")))\n\t}\n}\n\nfunc drainObject(obj client.Object) func(ctx context.Context) (client.Object, error) {\n\tpatch := client.MergeFrom(obj.DeepCopyObject().(client.Object))\n\tlabels := obj.GetLabels()\n\tdelete(labels, \"shard.alpha.sharding.timebertt.dev/\"+controllerRing.Name)\n\tobj.SetLabels(labels)\n\n\treturn func(ctx context.Context) (client.Object, error) {\n\t\treturn obj, testClient.Patch(ctx, obj, patch)\n\t}\n}\n"
  },
  {
    "path": "webhosting-operator/PROJECT",
    "content": "componentConfig: true\ndomain: timebertt.dev\nlayout:\n- go.kubebuilder.io/v3\nmultigroup: true\nprojectName: webhosting-operator\nrepo: github.com/timebertt/kubernetes-controller-sharding/webhosting-operator\nresources:\n- api:\n    crdVersion: v1\n    namespaced: true\n  controller: true\n  domain: timebertt.dev\n  group: webhosting\n  kind: Website\n  path: github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/apis/webhosting/v1alpha1\n  version: v1alpha1\n- api:\n    crdVersion: v1\n  controller: true\n  domain: timebertt.dev\n  group: webhosting\n  kind: Theme\n  path: github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/apis/webhosting/v1alpha1\n  version: v1alpha1\n- api:\n    crdVersion: v1\n    namespaced: true\n  domain: webhosting.timebertt.dev\n  group: config\n  kind: WebhostingOperatorConfig\n  path: github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/apis/config/v1alpha1\n  version: v1alpha1\nversion: \"3\"\n"
  },
  {
    "path": "webhosting-operator/README.md",
    "content": "# webhosting-operator\n\nwebhosting-operator is a simple operator developed using [kubebuilder](https://github.com/kubernetes-sigs/kubebuilder).\nIt is built for demonstrating and evaluating the implemented sharding mechanisms for Kubernetes controllers, see [Evaluating the Sharding Mechanism](../docs/evaluation.md).\n\nThe webhosting-operator is developed in a dedicated Go module so that its dependencies don't leak into the main module which also contains the shard library.\nThe webhosting-operator reuses the sharder components from the shard library as described in [Implement Sharding in Your Controller](../docs/implement-sharding.md).\n\nFor now, the webhosting-operator is kept in the same repository for simple evaluation of the project.\nHowever, it might be extracted into a dedicated repository later on if necessary.\n\n## Sample Operator Requirements\n\nTo demonstrate and evaluate the proposed sharding design, an operator is needed that fulfills the following requirements:\n\n- it should be composed of a single controller for one (custom) resource\n- in addition to watching its own resources, it needs to watch other relevant objects (e.g. owned objects) as well\n  - sharding is more difficult here, so add it as a challenge\n- it needs to deal with cluster-scoped objects (that are relevant for multiple namespaced objects)\n  - this adds side effects (duplicated cache) which need to be taken care of\n\n## Idea / Introduction\n\nThe idea behind this operator is simple: we want to build a web hosting platform on top of Kubernetes.\nI.e., we want to be able to configure websites for our customers in a declarative manner.\nThe desired state is configured via Kubernetes (custom) resources and the operator takes care to spin up websites and expose them.\n\nThere are three resources involved:\n\n- `Namespace`\n  - each customer project gets its own namespace\n  - a project namespace is identified by the `webhosting.timebertt.dev/project=true` label\n- `Theme` (API group `webhosting.timebertt.dev`, cluster-scoped)\n  - represents an offered theme for customer websites (managed by service admin)\n  - configures a font family and color for websites\n- `Website` (API group `webhosting.timebertt.dev`, namespaced)\n  - represents a single website a customer orders (managed by the customer in a project namespace)\n  - website simply displays the website's name (static)\n  - each website references exactly one theme\n  - deploys and configures a simple `nginx` deployment\n  - exposes the website via service and ingress\n\n## Setup\n\nTo test controller sharding with the webhosting-operator as an example controller, see [Evaluation](../docs/evaluation.md).\n"
  },
  {
    "path": "webhosting-operator/cmd/experiment/main.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage main\n\nimport (\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n\t\"github.com/spf13/cobra\"\n\t\"go.uber.org/zap/zapcore\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\tutilruntime \"k8s.io/apimachinery/pkg/util/runtime\"\n\tclientgoscheme \"k8s.io/client-go/kubernetes/scheme\"\n\t\"k8s.io/klog/v2\"\n\tctrl \"sigs.k8s.io/controller-runtime\"\n\t\"sigs.k8s.io/controller-runtime/pkg/healthz\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\tmetricsserver \"sigs.k8s.io/controller-runtime/pkg/metrics/server\"\n\n\t// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)\n\t// to ensure that exec-entrypoint and run can make use of them.\n\t_ \"k8s.io/client-go/plugin/pkg/client/auth\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/utils\"\n\n\t// Import all scenarios\n\t_ \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/scenario/all\"\n)\n\nvar (\n\tlog    logr.Logger\n\tscheme = runtime.NewScheme()\n)\n\nfunc init() {\n\tutilruntime.Must(clientgoscheme.AddToScheme(scheme))\n\tutilruntime.Must(webhostingv1alpha1.AddToScheme(scheme))\n}\n\nfunc main() {\n\tzapOpts := zap.Options{\n\t\tTimeEncoder: zapcore.ISO8601TimeEncoder,\n\t}\n\n\tvar (\n\t\tmgr              manager.Manager\n\t\tselectedScenario experiment.Scenario\n\t)\n\n\tcmd := &cobra.Command{\n\t\tUse:  \"experiment\",\n\t\tArgs: cobra.NoArgs,\n\n\t\tSilenceErrors: true,\n\t\tPersistentPreRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\tcmd.SilenceUsage = true\n\n\t\t\tctrl.SetLogger(zap.New(zap.UseFlagOptions(&zapOpts)))\n\t\t\tlog = ctrl.Log\n\t\t\tklog.SetLogger(ctrl.Log)\n\n\t\t\tvar err error\n\t\t\tmgr, err = ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{\n\t\t\t\tScheme:                 scheme,\n\t\t\t\tHealthProbeBindAddress: \":8081\",\n\t\t\t\tMetrics: metricsserver.Options{\n\t\t\t\t\tBindAddress: \":8080\",\n\t\t\t\t},\n\t\t\t\t// disable leader election\n\t\t\t\tLeaderElection: false,\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif err := mgr.AddHealthzCheck(\"healthz\", healthz.Ping); err != nil {\n\t\t\t\treturn fmt.Errorf(\"unable to set up health check: %w\", err)\n\t\t\t}\n\t\t\tif err := mgr.AddReadyzCheck(\"readyz\", healthz.Ping); err != nil {\n\t\t\t\treturn fmt.Errorf(\"unable to set up ready check: %w\", err)\n\t\t\t}\n\n\t\t\treturn nil\n\t\t},\n\t\tPersistentPostRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\tif err := selectedScenario.AddToManager(mgr); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tctx, cancel := context.WithCancel(cmd.Context())\n\t\t\tdefer cancel()\n\n\t\t\tgo func() {\n\t\t\t\tselect {\n\t\t\t\tcase <-ctx.Done():\n\t\t\t\tcase <-selectedScenario.Done():\n\t\t\t\t\t// stop the manager when scenario is done\n\t\t\t\t\tif utils.RunningInCluster() {\n\t\t\t\t\t\t// but give monitoring a bit more time to scrape the final metrics values if running in a cluster\n\t\t\t\t\t\t<-time.After(time.Minute)\n\t\t\t\t\t}\n\t\t\t\t\tcancel()\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\tlog.Info(\"Starting manager\")\n\t\t\treturn mgr.Start(ctx)\n\t\t},\n\t}\n\n\tzapOpts.BindFlags(flag.CommandLine)\n\tcmd.PersistentFlags().AddGoFlagSet(flag.CommandLine)\n\n\tgroup := cobra.Group{\n\t\tID:    \"scenarios\",\n\t\tTitle: \"Available Scenarios\",\n\t}\n\tcmd.AddGroup(&group)\n\n\tfor _, scenario := range experiment.GetAllScenarios() {\n\t\tcmd.AddCommand(&cobra.Command{\n\t\t\tUse:     scenario.Name(),\n\t\t\tShort:   scenario.Description(),\n\t\t\tLong:    scenario.LongDescription(),\n\t\t\tArgs:    cobra.NoArgs,\n\t\t\tGroupID: group.ID,\n\t\t\tRun: func(cmd *cobra.Command, args []string) {\n\t\t\t\tselectedScenario = scenario\n\t\t\t},\n\t\t})\n\t}\n\n\tif err := cmd.ExecuteContext(ctrl.SetupSignalHandler()); err != nil {\n\t\tfmt.Printf(\"Error running experiment: %v\\n\", err)\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "webhosting-operator/cmd/measure/main.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage main\n\nimport (\n\t\"context\"\n\t\"encoding/csv\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"slices\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/prometheus/client_golang/api\"\n\t\"github.com/prometheus/client_golang/api/prometheus/v1\"\n\t\"github.com/prometheus/common/model\"\n\t\"github.com/spf13/cobra\"\n\t\"gopkg.in/yaml.v3\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager/signals\"\n)\n\nconst (\n\tstdin  = \"-\"\n\tstdout = \"-\"\n)\n\nvar (\n\tnow = time.Now()\n\n\tqueriesInput io.Reader\n\toutputDir    string\n\toutputPrefix string\n\n\tprometheusURL = \"http://localhost:9091\"\n\tqueryRange    = v1.Range{\n\t\tStart: now.Add(-15 * time.Minute),\n\t\tEnd:   now,\n\t\tStep:  15 * time.Second,\n\t}\n)\n\nfunc main() {\n\tcmd := &cobra.Command{\n\t\tUse:  \"measure QUERIES_FILE|-\",\n\t\tArgs: cobra.ExactArgs(1),\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\tqueriesFileName := args[0]\n\t\t\tif queriesFileName == stdin {\n\t\t\t\tqueriesInput = os.Stdin\n\t\t\t} else {\n\t\t\t\tfile, err := os.Open(queriesFileName)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tdefer file.Close()\n\t\t\t\tqueriesInput = file\n\t\t\t}\n\n\t\t\tc, err := newClient()\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error creating prometheus client: %w\", err)\n\t\t\t}\n\n\t\t\tcmd.SilenceUsage = true\n\n\t\t\treturn run(cmd.Context(), c)\n\t\t},\n\t}\n\n\tcmd.Flags().StringVarP(&outputDir, \"output-dir\", \"o\", outputDir, \"Directory to write output files to, - for stdout (defaults to working directory)\")\n\tcmd.Flags().StringVar(&outputPrefix, \"output-prefix\", outputPrefix, \"Prefix to prepend to all output files\")\n\tcmd.Flags().StringVar(&prometheusURL, \"prometheus-url\", prometheusURL, \"URL for querying prometheus\")\n\tcmd.Flags().DurationVar(&queryRange.Step, \"step\", queryRange.Step, \"Query resolution step width\")\n\tcmd.Flags().Var((*timeValue)(&queryRange.Start), \"start\", \"Query start timestamp (RFC3339/duration relative to now/unix timestamp in seconds), inclusive (defaults to now-15m)\")\n\tcmd.Flags().Var((*timeValue)(&queryRange.End), \"end\", \"Query end timestamp (RFC3339/duration relative to now/unix timestamp in seconds), inclusive (defaults to now)\")\n\n\tif err := cmd.ExecuteContext(signals.SetupSignalHandler()); err != nil {\n\t\tos.Exit(1)\n\t}\n}\n\n// timeValue implements pflag.Value for specifying a timestamp in one of the following formats:\n//   - RFC3339, e.g. 2006-01-02T15:04:05Z07:00\n//   - duration relative to now, e.g. -5m\n//   - unix timestamp in seconds, e.g. 1665825136\ntype timeValue time.Time\n\nfunc (t *timeValue) Type() string   { return \"time\" }\nfunc (t *timeValue) String() string { return (*time.Time)(t).UTC().Format(time.RFC3339) }\n\nfunc (t *timeValue) Set(s string) error {\n\t// first try RFC3339 timestamp\n\ttt, err := time.Parse(time.RFC3339, s)\n\tif err == nil {\n\t\t*t = timeValue(tt)\n\t\treturn nil\n\t}\n\n\t// then try duration\n\tdd, err := time.ParseDuration(s)\n\tif err == nil {\n\t\t*t = timeValue(time.Now().Add(dd))\n\t\treturn nil\n\t}\n\n\t// lastly try unix timestamp\n\tii, err := strconv.ParseInt(s, 10, 64)\n\tif err == nil {\n\t\t*t = timeValue(time.Unix(ii, 0))\n\t\treturn nil\n\t}\n\n\treturn fmt.Errorf(\"invalid time value: %q\", s)\n}\n\nfunc newClient() (v1.API, error) {\n\tapiClient, err := api.NewClient(api.Config{\n\t\tAddress: prometheusURL,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn v1.NewAPI(apiClient), nil\n}\n\nconst (\n\tQueryTypeInstant = \"instant\"\n\tQueryTypeRange   = \"range\"\n)\n\ntype QueriesConfig struct {\n\tQueries []Query `yaml:\"queries\"`\n}\n\ntype Query struct {\n\tName string `yaml:\"name\"`\n\t// range or instant, defaults to range.\n\t// If instant is specified, the $__range variable in the query is substituted by the configured range's duration.\n\tType     string `yaml:\"type,omitempty\"`\n\tQuery    string `yaml:\"query\"`\n\tOptional bool   `yaml:\"optional,omitempty\"`\n\t// upper threshold for values\n\tSLO *float64 `yaml:\"slo,omitempty\"`\n}\n\nfunc run(ctx context.Context, c v1.API) error {\n\tconfig, err := decodeQueriesConfig()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error decoding queries file: %w\", err)\n\t}\n\n\tif err = prepareOutputDir(); err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Printf(\"Using time range for query: %s\\n\", rangeToString(queryRange))\n\n\tvar (\n\t\tslosChecked = false\n\t\tslosMet     = true\n\t)\n\n\tfor _, q := range config.Queries {\n\t\tdata, err := q.fetchData(ctx, c)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error fetching data for query %q: %w\", q.Name, err)\n\t\t}\n\n\t\tif data.IsEmpty() {\n\t\t\tif q.Optional {\n\t\t\t\tfmt.Printf(\"Skipping output for query %q as data is empty\\n\", q.Name)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"data is empty for query %q, but query is required\", q.Name)\n\t\t}\n\n\t\tif err = q.writeResult(data); err != nil {\n\t\t\treturn fmt.Errorf(\"error writing result: %w\", err)\n\t\t}\n\n\t\tif checked, ok := q.verifySLO(data); checked {\n\t\t\tslosChecked = true\n\t\t\tif !ok {\n\t\t\t\tslosMet = false\n\t\t\t}\n\t\t}\n\t}\n\n\tif slosChecked {\n\t\tif !slosMet {\n\t\t\treturn fmt.Errorf(\"❌ SLO verifications failed\")\n\t\t}\n\n\t\tfmt.Println(\"✅ SLO verifications succeeded\")\n\t} else {\n\t\tfmt.Println(\"ℹ️ No SLOs defined\")\n\t}\n\n\treturn nil\n}\n\nfunc decodeQueriesConfig() (*QueriesConfig, error) {\n\tconfigData, err := io.ReadAll(queriesInput)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tc := &QueriesConfig{}\n\treturn c, yaml.Unmarshal(configData, c)\n}\n\nfunc prepareOutputDir() error {\n\tif outputDir == stdout {\n\t\treturn nil\n\t}\n\tif outputDir == \"\" {\n\t\toutputDir = \".\"\n\t}\n\n\tif err := os.MkdirAll(outputDir, 0750); err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Printf(\"Writing output files to %s\\n\", outputDir)\n\treturn nil\n}\n\nfunc (q Query) fetchData(ctx context.Context, c v1.API) (metricData, error) {\n\topts := []v1.Option{v1.WithTimeout(10 * time.Second)}\n\n\tvar (\n\t\tdata     metricData\n\t\tresult   model.Value\n\t\twarnings v1.Warnings\n\t\terr      error\n\t)\n\n\tswitch q.Type {\n\tcase QueryTypeRange, \"\":\n\t\tresult, warnings, err = c.QueryRange(ctx, q.Query, queryRange, opts...)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tmatrix, ok := result.(model.Matrix)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"unexpected value type %q for query %q, expected matrix\", result.Type().String(), q.Name)\n\t\t}\n\t\tdata = &matrixData{Matrix: matrix}\n\n\tcase QueryTypeInstant:\n\t\trangeString := queryRange.End.Sub(queryRange.Start).String()\n\t\tquery := q.Query\n\t\tquery = strings.ReplaceAll(query, \"$__range\", rangeString)\n\n\t\tresult, warnings, err = c.Query(ctx, query, queryRange.End, opts...)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tvector, ok := result.(model.Vector)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"unexpected value type %q for query %q, expected vector\", result.Type().String(), q.Name)\n\t\t}\n\t\tdata = &vectorData{Vector: vector}\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported query type %q\", q.Type)\n\t}\n\n\tif len(warnings) > 0 {\n\t\tfmt.Printf(\"Warnings: %v\\n\", warnings)\n\t}\n\n\treturn data, nil\n}\n\nfunc (q Query) writeResult(data metricData) error {\n\tfileName := outputPrefix + q.Name + \".csv\"\n\n\tvar out io.Writer\n\tif outputDir == stdout {\n\t\tout = os.Stdout\n\t\tfmt.Println(\"# \" + fileName)\n\t} else {\n\t\tfile, err := os.OpenFile(filepath.Join(outputDir, fileName), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer file.Close()\n\t\tout = file\n\t}\n\n\t// go maps are unsorted -> need to sort labels by name so that all values end up in the right column\n\tlabelNames := data.GetLabelNames()\n\tslices.Sort(labelNames)\n\n\t// write header\n\tw := csv.NewWriter(out)\n\tif err := w.Write(append([]string{\"ts\", \"value\"}, toStringSlice(labelNames)...)); err != nil {\n\t\treturn err\n\t}\n\n\t// write contents\n\tdata.Reset()\n\tfor {\n\t\tvalue := data.NextValue()\n\t\tif value.IsZero() { // end of results\n\t\t\tbreak\n\t\t}\n\n\t\tlabelValues := make([]string, len(labelNames))\n\t\tfor i, name := range labelNames {\n\t\t\tlabelValues[i] = string(value.metric[name])\n\t\t}\n\n\t\tif err := w.Write(append([]string{\n\t\t\tstrconv.FormatInt(value.time.Unix(), 10),\n\t\t\tstrconv.FormatFloat(value.value, 'f', -1, 64),\n\t\t}, labelValues...)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tw.Flush()\n\tif err := w.Error(); err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Printf(\"Successfully written output to %s\\n\", fileName)\n\treturn nil\n}\n\nfunc (q Query) verifySLO(data metricData) (checked bool, ok bool) {\n\tif q.SLO == nil {\n\t\treturn false, true\n\t}\n\n\tvar allFailures []string\n\n\tdata.Reset()\n\tfor {\n\t\tvalue := data.NextValue()\n\t\tif value.IsZero() { // end of results\n\t\t\tbreak\n\t\t}\n\n\t\tif math.IsNaN(value.value) || value.value <= *q.SLO {\n\t\t\tcontinue\n\t\t}\n\n\t\tallFailures = append(allFailures, fmt.Sprintf(\"%s => %f @[%s]\", value.metric, value.value, value.time.Format(time.RFC3339)))\n\t}\n\n\tif len(allFailures) > 0 {\n\t\tindent := \"- \"\n\t\tfmt.Printf(\"❌ SLO for query %q (<= %f) is not met:\\n%s\\n\", q.Name, *q.SLO, indent+strings.Join(allFailures, \"\\n\"+indent))\n\t\treturn true, false\n\t}\n\n\tfmt.Printf(\"✅ SLO for query %q (<= %f) met\\n\", q.Name, *q.SLO)\n\treturn true, true\n}\n\nfunc rangeToString(r v1.Range) string {\n\treturn fmt.Sprintf(\"start:%s end:%s step:%s\", r.Start.UTC().Format(time.RFC3339), r.End.UTC().Format(time.RFC3339), r.Step.String())\n}\n\n// metricData gives cursor-style access to metric values, which could either be a matrix (for range queries) or a vector\n// (for instant queries).\ntype metricData interface {\n\t// IsEmpty returns true if the query result was empty.\n\tIsEmpty() bool\n\t// GetLabelNames returns an unsorted list of label names of the first metric.\n\tGetLabelNames() model.LabelNames\n\t// Reset resets the cursor.\n\tReset()\n\t// NextValue moves the cursor to the next metric value and returns it. It returns a zero metricValue at the end.\n\tNextValue() metricValue\n}\n\ntype metricValue struct {\n\tmetric model.Metric\n\ttime   time.Time\n\tvalue  float64\n}\n\nfunc (m metricValue) IsZero() bool {\n\treturn m.time.IsZero()\n}\n\ntype matrixData struct {\n\tmodel.Matrix\n\n\tcursor struct {\n\t\tmetric, value int\n\t}\n}\n\nfunc (m *matrixData) IsEmpty() bool {\n\treturn m.Len() == 0\n}\n\nfunc (m *matrixData) GetLabelNames() model.LabelNames {\n\tlabels := sets.New[model.LabelName]()\n\n\tfor _, metric := range m.Matrix {\n\t\tfor labelName := range metric.Metric {\n\t\t\tif labelName == model.MetricNameLabel {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlabels.Insert(labelName)\n\t\t}\n\t}\n\n\treturn labels.UnsortedList()\n}\n\nfunc (m *matrixData) Reset() {\n\tm.cursor.metric = 0\n\tm.cursor.value = 0\n}\n\nfunc (m *matrixData) NextValue() metricValue {\n\tif m.IsEmpty() {\n\t\treturn metricValue{}\n\t}\n\n\t// move to next metric if we already visited all values in the current metric\n\tif m.cursor.value >= len(m.Matrix[m.cursor.metric].Values) {\n\t\tm.cursor.metric++\n\t\tm.cursor.value = 0\n\t}\n\n\t// end of results\n\tif m.cursor.metric >= m.Len() {\n\t\treturn metricValue{}\n\t}\n\n\tsampleStream := m.Matrix[m.cursor.metric]\n\tvalue := sampleStream.Values[m.cursor.value]\n\n\t// move on to the next value in the current metric\n\tm.cursor.value++\n\n\treturn metricValue{\n\t\tmetric: sampleStream.Metric,\n\t\ttime:   value.Timestamp.Time(),\n\t\tvalue:  float64(value.Value),\n\t}\n}\n\ntype vectorData struct {\n\tmodel.Vector\n\n\tcursor int\n}\n\nfunc (v *vectorData) IsEmpty() bool {\n\treturn v.Len() == 0\n}\n\nfunc (v *vectorData) GetLabelNames() model.LabelNames {\n\tlabels := sets.New[model.LabelName]()\n\n\tfor _, metric := range v.Vector {\n\t\tfor labelName := range metric.Metric {\n\t\t\tif labelName == model.MetricNameLabel {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlabels.Insert(labelName)\n\t\t}\n\t}\n\n\treturn labels.UnsortedList()\n}\n\nfunc (v *vectorData) Reset() {\n\tv.cursor = 0\n}\n\nfunc (v *vectorData) NextValue() metricValue {\n\tif v.IsEmpty() {\n\t\treturn metricValue{}\n\t}\n\n\t// end of results\n\tif v.cursor >= len(v.Vector) {\n\t\treturn metricValue{}\n\t}\n\n\tsample := v.Vector[v.cursor]\n\n\t// move on to the next sample\n\tv.cursor++\n\n\treturn metricValue{\n\t\tmetric: sample.Metric,\n\t\ttime:   sample.Timestamp.Time(),\n\t\tvalue:  float64(sample.Value),\n\t}\n}\n\nfunc toStringSlice[S ~[]E, E ~string](s S) []string {\n\tout := make([]string, 0, len(s))\n\tfor _, v := range s {\n\t\tout = append(out, string(v))\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "webhosting-operator/cmd/measure/test.yaml",
    "content": "queries:\n- name: queue-rate-by-pod\n  type: range # returns a matrix\n  slo: 200\n  query: sum(rate(workqueue_adds_total{job=\"webhosting-operator\"}[1m])) by (pod)\n- name: queue-latency-by-controller\n  type: instant # returns a vector\n  slo: 0.1\n  query: |\n    histogram_quantile(0.99,\n      sum by (name, le) (rate(\n        workqueue_queue_duration_seconds_bucket{\n          job=\"webhosting-operator\",\n        }[$__range]\n      ))\n    )\n"
  },
  {
    "path": "webhosting-operator/cmd/samples-generator/main.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"os\"\n\n\t\"github.com/spf13/cobra\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\tutilruntime \"k8s.io/apimachinery/pkg/util/runtime\"\n\tclientgoscheme \"k8s.io/client-go/kubernetes/scheme\"\n\tctrl \"sigs.k8s.io/controller-runtime\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager/signals\"\n\n\t// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)\n\t// to ensure that exec-entrypoint and run can make use of them.\n\t_ \"k8s.io/client-go/plugin/pkg/client/auth\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/utils\"\n)\n\nvar (\n\tscheme = runtime.NewScheme()\n\n\tcount        int\n\tnamespaces   []string\n\tskipWorkload bool\n)\n\nfunc init() {\n\tutilruntime.Must(clientgoscheme.AddToScheme(scheme))\n\tutilruntime.Must(webhostingv1alpha1.AddToScheme(scheme))\n}\n\nfunc main() {\n\tcmd := &cobra.Command{\n\t\tUse:  \"samples-generator\",\n\t\tArgs: cobra.NoArgs,\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\tc, err := client.New(ctrl.GetConfigOrDie(), client.Options{Scheme: scheme})\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tcmd.SilenceUsage = true\n\n\t\t\treturn generateSamples(cmd.Context(), c)\n\t\t},\n\t}\n\n\tcmd.Flags().IntVarP(&count, \"count\", \"c\", count, \"number of websites to generate per project\")\n\tcmd.Flags().StringSliceVarP(&namespaces, \"namespace\", \"n\", namespaces, \"project namespaces to generate websites in\")\n\tcmd.Flags().BoolVar(&skipWorkload, \"skip-workload\", false, \"don't run any actual workload for the generated websites\")\n\n\tif err := cmd.ExecuteContext(signals.SetupSignalHandler()); err != nil {\n\t\tfmt.Printf(\"Error generating samples: %v\\n\", err)\n\t\tos.Exit(1)\n\t}\n}\n\nfunc generateSamples(ctx context.Context, c client.Client) error {\n\tthemeList := &webhostingv1alpha1.ThemeList{}\n\tif err := c.List(ctx, themeList); err != nil {\n\t\treturn err\n\t}\n\n\tthemes := make([]string, 0, len(themeList.Items))\n\tfor _, theme := range themeList.Items {\n\t\tthemes = append(themes, theme.Name)\n\t}\n\n\tif len(themes) == 0 {\n\t\treturn fmt.Errorf(\"no themes found, create them first\")\n\t}\n\n\tnamespaceList := &corev1.NamespaceList{}\n\tif err := c.List(ctx, namespaceList, client.MatchingLabelsSelector{Selector: webhostingv1alpha1.LabelSelectorProject}); err != nil {\n\t\treturn err\n\t}\n\n\tif len(namespaceList.Items) == 0 {\n\t\treturn fmt.Errorf(\"no project namespaces found, create namespaces with the %q label first\", webhostingv1alpha1.LabelKeyProject)\n\t}\n\n\tfor _, namespace := range namespaceList.Items {\n\t\tproject := namespace.Name\n\n\t\t// nolint:gosec // doesn't need to be cryptographically secure\n\t\twebsiteCount := rand.Intn(50) + 1\n\t\tif count > 0 {\n\t\t\twebsiteCount = count\n\t\t}\n\n\t\tfor i := 0; i < websiteCount; i++ {\n\t\t\twebsite := &webhostingv1alpha1.Website{\n\t\t\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\t\t\tName:      \"sample-\" + utils.RandomName(8),\n\t\t\t\t\tNamespace: project,\n\t\t\t\t\tLabels: map[string]string{\n\t\t\t\t\t\t\"generated-by\": \"samples-generator\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSpec: webhostingv1alpha1.WebsiteSpec{\n\t\t\t\t\tTheme: utils.PickRandom(themes),\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tif skipWorkload {\n\t\t\t\twebsite.Labels[webhostingv1alpha1.LabelKeySkipWorkload] = \"true\"\n\t\t\t}\n\n\t\t\tif err := c.Create(ctx, website); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tfmt.Printf(\"created %d Websites in project %q\\n\", websiteCount, project)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "webhosting-operator/cmd/webhosting-operator/main.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\tgoruntime \"runtime\"\n\t\"strconv\"\n\n\t\"go.uber.org/zap/zapcore\"\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tnetworkingv1 \"k8s.io/api/networking/v1\"\n\t\"k8s.io/apimachinery/pkg/labels\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/runtime/serializer\"\n\tutilruntime \"k8s.io/apimachinery/pkg/util/runtime\"\n\tclientgoscheme \"k8s.io/client-go/kubernetes/scheme\"\n\t\"k8s.io/client-go/rest\"\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/utils/ptr\"\n\tctrl \"sigs.k8s.io/controller-runtime\"\n\t\"sigs.k8s.io/controller-runtime/pkg/cache\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/healthz\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\t\"sigs.k8s.io/controller-runtime/pkg/metrics/filters\"\n\tmetricsserver \"sigs.k8s.io/controller-runtime/pkg/metrics/server\"\n\n\t// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)\n\t// to ensure that exec-entrypoint and run can make use of them.\n\t_ \"k8s.io/client-go/plugin/pkg/client/auth\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\tshardlease \"github.com/timebertt/kubernetes-controller-sharding/pkg/shard/lease\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/routes\"\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/config/v1alpha1\"\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/controllers/webhosting\"\n\twebhostingmetrics \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/metrics\"\n\t//+kubebuilder:scaffold:imports\n)\n\nvar (\n\tscheme   = runtime.NewScheme()\n\tsetupLog = ctrl.Log.WithName(\"setup\")\n)\n\nfunc init() {\n\tutilruntime.Must(clientgoscheme.AddToScheme(scheme))\n\n\tutilruntime.Must(webhostingv1alpha1.AddToScheme(scheme))\n\tutilruntime.Must(configv1alpha1.AddToScheme(scheme))\n\t//+kubebuilder:scaffold:scheme\n}\n\nfunc main() {\n\tctx := ctrl.SetupSignalHandler()\n\topts := options{}\n\topts.AddFlags(flag.CommandLine)\n\n\tzapOpts := zap.Options{\n\t\tTimeEncoder: zapcore.ISO8601TimeEncoder,\n\t}\n\tzapOpts.BindFlags(flag.CommandLine)\n\tflag.Parse()\n\n\tctrl.SetLogger(zap.New(zap.UseFlagOptions(&zapOpts)))\n\tklog.SetLogger(ctrl.Log)\n\n\tif err := opts.Complete(); err != nil {\n\t\tsetupLog.Error(err, \"unable to load config\")\n\t\tos.Exit(1)\n\t}\n\n\tmgr, err := ctrl.NewManager(opts.restConfig, opts.managerOptions)\n\tif err != nil {\n\t\tsetupLog.Error(err, \"unable to start manager\")\n\t\tos.Exit(1)\n\t}\n\n\tif err = (&webhosting.WebsiteReconciler{\n\t\tConfig: opts.config,\n\t}).SetupWithManager(mgr, opts.enableSharding, opts.controllerRingName, opts.shardName); err != nil {\n\t\tsetupLog.Error(err, \"unable to create controller\", \"controller\", \"Website\")\n\t\tos.Exit(1)\n\t}\n\n\tif err = webhostingmetrics.AddToManager(mgr); err != nil {\n\t\tsetupLog.Error(err, \"unable to add metrics exporters\")\n\t\tos.Exit(1)\n\t}\n\n\t//+kubebuilder:scaffold:builder\n\n\tif err := mgr.AddHealthzCheck(\"healthz\", healthz.Ping); err != nil {\n\t\tsetupLog.Error(err, \"unable to set up health check\")\n\t\tos.Exit(1)\n\t}\n\tif err := mgr.AddReadyzCheck(\"readyz\", healthz.Ping); err != nil {\n\t\tsetupLog.Error(err, \"unable to set up ready check\")\n\t\tos.Exit(1)\n\t}\n\n\tsetupLog.Info(\"starting manager\")\n\tif err := mgr.Start(ctx); err != nil {\n\t\tsetupLog.Error(err, \"problem running manager\")\n\t\tos.Exit(1)\n\t}\n}\n\ntype options struct {\n\tconfigFile string\n\n\trestConfig         *rest.Config\n\tconfig             *configv1alpha1.WebhostingOperatorConfig\n\tmanagerOptions     ctrl.Options\n\tenableSharding     bool\n\tcontrollerRingName string\n\tshardName          string\n}\n\nfunc (o *options) AddFlags(fs *flag.FlagSet) {\n\tfs.StringVar(&o.configFile, \"config\", \"\",\n\t\t\"Path to the file containing the operator's configuration (WebhostingOperatorConfig). \"+\n\t\t\t\"If not specified, the operator will use the default configuration values.\")\n}\n\nfunc (o *options) Complete() error {\n\to.config = &configv1alpha1.WebhostingOperatorConfig{}\n\n\t// load config file if specified\n\tif o.configFile != \"\" {\n\t\tconfigBytes, err := os.ReadFile(o.configFile)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed reading config file: %w\", err)\n\t\t}\n\n\t\tif err := runtime.DecodeInto(serializer.NewCodecFactory(scheme).UniversalDecoder(), configBytes, o.config); err != nil {\n\t\t\treturn fmt.Errorf(\"failed decoding config file: %w\", err)\n\t\t}\n\t} else {\n\t\tscheme.Default(o.config)\n\t}\n\n\t// load rest config\n\tvar err error\n\to.restConfig, err = ctrl.GetConfig()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed loading kubeconfig: %w\", err)\n\t}\n\n\t// bring everything together\n\to.managerOptions = ctrl.Options{\n\t\tScheme: scheme,\n\t\t// allows us to quickly handover leadership on restarts\n\t\tLeaderElectionReleaseOnCancel: true,\n\t\tCache: cache.Options{\n\t\t\tDefaultTransform: dropUnwantedMetadata,\n\t\t},\n\t}\n\n\to.applyConfigToRESTConfig()\n\to.applyConfigToOptions()\n\tif err := o.applyOptionsOverrides(); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (o *options) applyConfigToRESTConfig() {\n\tif clientConnection := o.config.ClientConnection; clientConnection != nil {\n\t\tif clientConnection.QPS > 0 {\n\t\t\to.restConfig.QPS = clientConnection.QPS\n\t\t}\n\t\tif clientConnection.Burst > 0 {\n\t\t\to.restConfig.Burst = int(clientConnection.Burst)\n\t\t}\n\t}\n}\n\nfunc (o *options) applyConfigToOptions() {\n\tif leaderElection := o.config.LeaderElection; leaderElection != nil {\n\t\to.managerOptions.LeaderElection = *leaderElection.LeaderElect\n\t\to.managerOptions.LeaderElectionResourceLock = leaderElection.ResourceLock\n\t\to.managerOptions.LeaderElectionID = leaderElection.ResourceName\n\t\to.managerOptions.LeaderElectionNamespace = leaderElection.ResourceNamespace\n\t\to.managerOptions.LeaseDuration = ptr.To(leaderElection.LeaseDuration.Duration)\n\t\to.managerOptions.RenewDeadline = ptr.To(leaderElection.RenewDeadline.Duration)\n\t\to.managerOptions.RetryPeriod = ptr.To(leaderElection.RetryPeriod.Duration)\n\t}\n\n\to.managerOptions.HealthProbeBindAddress = o.config.Health.BindAddress\n\n\tif o.config.Metrics.BindAddress != \"0\" {\n\t\tvar extraHandlers map[string]http.Handler\n\t\tif *o.config.Debugging.EnableProfiling {\n\t\t\textraHandlers = routes.ProfilingHandlers\n\t\t\tif *o.config.Debugging.EnableContentionProfiling {\n\t\t\t\tgoruntime.SetBlockProfileRate(1)\n\t\t\t}\n\t\t}\n\n\t\to.managerOptions.Metrics = metricsserver.Options{\n\t\t\tSecureServing:  true,\n\t\t\tBindAddress:    o.config.Metrics.BindAddress,\n\t\t\tFilterProvider: filters.WithAuthenticationAndAuthorization,\n\t\t\tExtraHandlers:  extraHandlers,\n\t\t}\n\t}\n\n\to.managerOptions.GracefulShutdownTimeout = ptr.To(o.config.GracefulShutdownTimeout.Duration)\n}\n\nfunc (o *options) applyOptionsOverrides() error {\n\tvar err error\n\n\t// allow overriding leader election via env var for debugging purposes\n\tif leaderElectEnv, ok := os.LookupEnv(\"LEADER_ELECT\"); ok {\n\t\to.managerOptions.LeaderElection, err = strconv.ParseBool(leaderElectEnv)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error parsing LEADER_ELECT env var: %w\", err)\n\t\t}\n\t}\n\n\t// allow enabling/disabling sharding via env var for evaluation\n\tif shardingEnv, ok := os.LookupEnv(\"ENABLE_SHARDING\"); ok {\n\t\to.enableSharding, err = strconv.ParseBool(shardingEnv)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error parsing ENABLE_SHARDING env var: %w\", err)\n\t\t}\n\t}\n\n\tif o.enableSharding {\n\t\tif !o.managerOptions.LeaderElection {\n\t\t\treturn fmt.Errorf(\"sharding cannot be enabled if leader election is disabled\")\n\t\t}\n\n\t\t// SHARD LEASE\n\t\to.controllerRingName = webhostingv1alpha1.WebhostingOperatorName\n\t\tshardLease, err := shardlease.NewResourceLock(o.restConfig, shardlease.Options{\n\t\t\tControllerRingName: o.controllerRingName,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed creating shard lease: %w\", err)\n\t\t}\n\t\to.shardName = shardLease.Identity()\n\n\t\t// Use manager's leader election mechanism for maintaining the shard lease.\n\t\t// With this, controllers will only run as long as manager holds the shard lease.\n\t\t// After graceful termination, the shard lease will be released.\n\t\to.managerOptions.LeaderElectionResourceLockInterface = shardLease\n\n\t\t// FILTERED WATCH CACHE\n\t\t// Configure cache to only watch objects that are assigned to this shard.\n\t\tshardLabelSelector := labels.SelectorFromSet(labels.Set{\n\t\t\tshardingv1alpha1.LabelShard(o.controllerRingName): o.shardName,\n\t\t})\n\n\t\t// This operator watches sharded objects (Websites, etc.) as well as non-sharded objects (Themes),\n\t\t// use cache.Options.ByObject to configure the label selector on object level.\n\t\to.managerOptions.Cache.ByObject = map[client.Object]cache.ByObject{\n\t\t\t&webhostingv1alpha1.Website{}: {Label: shardLabelSelector},\n\t\t\t&appsv1.Deployment{}:          {Label: shardLabelSelector},\n\t\t\t&corev1.ConfigMap{}:           {Label: shardLabelSelector},\n\t\t\t&corev1.Service{}:             {Label: shardLabelSelector},\n\t\t\t&networkingv1.Ingress{}:       {Label: shardLabelSelector},\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc dropUnwantedMetadata(i interface{}) (interface{}, error) {\n\tobj, ok := i.(client.Object)\n\tif !ok {\n\t\treturn i, nil\n\t}\n\n\tobj.SetManagedFields(nil)\n\tannotations := obj.GetAnnotations()\n\tdelete(annotations, \"kubectl.kubernetes.io/last-applied-configuration\")\n\tobj.SetAnnotations(annotations)\n\n\treturn obj, nil\n}\n"
  },
  {
    "path": "webhosting-operator/config/experiment/base/job.yaml",
    "content": "apiVersion: batch/v1\nkind: Job\nmetadata:\n  name: experiment\nspec:\n  # don't retry this job as it might not leave behind a clean cluster -> retries will not provide meaningful results\n  backoffLimit: 0\n  activeDeadlineSeconds: 1200\n  ttlSecondsAfterFinished: 300\n  template:\n    spec:\n      containers:\n      - name: experiment\n        image: experiment:latest\n        args:\n        - --zap-devel\n        env:\n        - name: RUN_ID\n          valueFrom:\n            fieldRef:\n              fieldPath: metadata.uid\n        - name: DISABLE_HTTP2\n          value: \"true\"\n        ports:\n        - name: metrics\n          containerPort: 8080\n          protocol: TCP\n        securityContext:\n          allowPrivilegeEscalation: false\n        livenessProbe:\n          httpGet:\n            path: /healthz\n            port: 8081\n          initialDelaySeconds: 15\n          periodSeconds: 20\n        readinessProbe:\n          httpGet:\n            path: /readyz\n            port: 8081\n          initialDelaySeconds: 5\n          periodSeconds: 10\n        resources:\n          limits:\n            cpu: \"4\"\n            memory: 512Mi\n          requests:\n            cpu: \"2\"\n            memory: 256Mi\n      restartPolicy: Never\n      securityContext:\n        runAsNonRoot: true\n      serviceAccountName: experiment\n      terminationGracePeriodSeconds: 30\n"
  },
  {
    "path": "webhosting-operator/config/experiment/base/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nnamespace: experiment\n\nlabels:\n- includeSelectors: true\n  pairs:\n    app.kubernetes.io/name: experiment\n\nimages:\n- name: experiment\n  newName: ghcr.io/timebertt/kubernetes-controller-sharding/experiment\n  newTag: latest\n\nresources:\n- namespace.yaml\n- job.yaml\n- rbac.yaml\n- service.yaml\n# provide prometheus running in namespace \"monitoring\" with the permissions required for service discovery in namespace\n# \"experiment\"\n- prometheus_rbac.yaml\n- servicemonitor.yaml\n"
  },
  {
    "path": "webhosting-operator/config/experiment/base/namespace.yaml",
    "content": "apiVersion: v1\nkind: Namespace\nmetadata:\n  name: experiment\n"
  },
  {
    "path": "webhosting-operator/config/experiment/base/prometheus_rbac.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n  name: prometheus-k8s\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - services\n  - endpoints\n  - pods\n  verbs:\n  - get\n  - list\n  - watch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n  name: prometheus-k8s\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: prometheus-k8s\nsubjects:\n- kind: ServiceAccount\n  name: prometheus-k8s\n  namespace: monitoring\n"
  },
  {
    "path": "webhosting-operator/config/experiment/base/rbac.yaml",
    "content": "---\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: experiment\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: experiment\nrules:\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - themes\n  - websites\n  verbs:\n  - get\n  - list\n  - watch\n  - create\n  - patch\n  - update\n  - delete\n  - deletecollection\n- apiGroups:\n  - \"\"\n  resources:\n  - namespaces\n  verbs:\n  - get\n  - list\n  - watch\n  - create\n  - patch\n  - update\n  - delete\n  - deletecollection\n- apiGroups:\n  - rbac.authorization.k8s.io\n  resources:\n  - clusterroles\n  verbs:\n  - create\n  - delete\n- apiGroups:\n  - apps\n  resources:\n  - deployments\n  verbs:\n  - get\n  - list\n  - watch\n  - patch\n- apiGroups:\n  - coordination.k8s.io\n  resources:\n  - leases\n  verbs:\n  - get\n  - list\n  - watch\n  - deletecollection\n- apiGroups:\n  - \"\"\n  resources:\n  - pods\n  verbs:\n  - get\n  - list\n  - watch\n  - delete\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: experiment\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: experiment\nsubjects:\n- kind: ServiceAccount\n  name: experiment\n"
  },
  {
    "path": "webhosting-operator/config/experiment/base/service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: experiment\n  namespace: system\nspec:\n  ports:\n  - name: metrics\n    port: 8080\n    protocol: TCP\n    targetPort: metrics\n"
  },
  {
    "path": "webhosting-operator/config/experiment/base/servicemonitor.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  name: experiment\nspec:\n  endpoints:\n  - path: /metrics\n    port: metrics\n    scheme: http\n    bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    interval: 10s\n    scrapeTimeout: 10s\n    relabelings:\n    - targetLabel: job\n      replacement: experiment\n    - targetLabel: run_id\n      sourceLabels: [__meta_kubernetes_pod_uid]\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: experiment\n"
  },
  {
    "path": "webhosting-operator/config/experiment/basic/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../base\n\npatches:\n- target:\n    kind: Job\n    name: experiment\n  patch: |\n    - op: add\n      path: /spec/template/spec/containers/0/args/-\n      value: basic\n"
  },
  {
    "path": "webhosting-operator/config/experiment/chaos/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../base\n\npatches:\n- target:\n    kind: Job\n    name: experiment\n  patch: |\n    - op: add\n      path: /spec/template/spec/containers/0/args/-\n      value: chaos\n"
  },
  {
    "path": "webhosting-operator/config/experiment/rolling-update/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../base\n\npatches:\n- target:\n    kind: Job\n    name: experiment\n  patch: |\n    - op: add\n      path: /spec/template/spec/containers/0/args/-\n      value: rolling-update\n"
  },
  {
    "path": "webhosting-operator/config/experiment/scale-out/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../base\n\npatches:\n- target:\n    kind: Job\n    name: experiment\n  patch: |\n    - op: add\n      path: /spec/template/spec/containers/0/args/-\n      value: scale-out\n"
  },
  {
    "path": "webhosting-operator/config/manager/base/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\n# Adds namespace to all resources.\nnamespace: webhosting-system\n\n# Value of this field is prepended to the\n# names of all resources, e.g. a deployment named\n# \"wordpress\" becomes \"alices-wordpress\".\n# Note that it should also match with the prefix (text before '-') of the namespace\n# field above.\nnamePrefix: webhosting-\n\n# Labels to add to all resources and selectors.\nlabels:\n- includeSelectors: true\n  pairs:\n    app.kubernetes.io/name: webhosting-operator\n\nimages:\n- name: controller\n  newName: ghcr.io/timebertt/kubernetes-controller-sharding/webhosting-operator\n  newTag: latest\n\nresources:\n- namespace.yaml\n- manager.yaml\n- service.yaml\n- ../crds\n- ../rbac\n- metrics_auth.yaml\n"
  },
  {
    "path": "webhosting-operator/config/manager/base/manager.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: operator\n  namespace: system\nspec:\n  replicas: 3\n  template:\n    metadata:\n      annotations:\n        kubectl.kubernetes.io/default-container: manager\n    spec:\n      automountServiceAccountToken: true\n      securityContext:\n        runAsNonRoot: true\n      containers:\n      - name: manager\n        image: controller:latest\n        args: []\n        env:\n        - name: DISABLE_HTTP2\n          value: \"true\"\n        - name: WEBSITE_CONCURRENT_SYNCS\n          value: \"15\"\n        ports:\n        - name: metrics\n          containerPort: 8080\n          protocol: TCP\n        securityContext:\n          allowPrivilegeEscalation: false\n        livenessProbe:\n          httpGet:\n            path: /healthz\n            port: 8081\n          initialDelaySeconds: 15\n          periodSeconds: 20\n        readinessProbe:\n          httpGet:\n            path: /readyz\n            port: 8081\n          initialDelaySeconds: 5\n          periodSeconds: 10\n        resources:\n          limits:\n            cpu: \"2\"\n            memory: 1Gi\n          requests:\n            cpu: \"1\"\n            memory: 512Mi\n      serviceAccountName: operator\n      terminationGracePeriodSeconds: 30\n"
  },
  {
    "path": "webhosting-operator/config/manager/base/metrics_auth.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: operator-metrics-auth\nrules:\n- apiGroups:\n  - authentication.k8s.io\n  resources:\n  - tokenreviews\n  verbs:\n  - create\n- apiGroups:\n  - authorization.k8s.io\n  resources:\n  - subjectaccessreviews\n  verbs:\n  - create\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: operator-metrics-auth\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: operator-metrics-auth\nsubjects:\n- kind: ServiceAccount\n  name: operator\n  namespace: system\n"
  },
  {
    "path": "webhosting-operator/config/manager/base/namespace.yaml",
    "content": "apiVersion: v1\nkind: Namespace\nmetadata:\n  name: system\n"
  },
  {
    "path": "webhosting-operator/config/manager/base/service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: operator\nspec:\n  type: ClusterIP\n  ports:\n  - port: 8080\n    name: metrics\n    protocol: TCP\n    targetPort: metrics\n"
  },
  {
    "path": "webhosting-operator/config/manager/controllerring/controllerring.yaml",
    "content": "apiVersion: sharding.timebertt.dev/v1alpha1\nkind: ControllerRing\nmetadata:\n  name: webhosting-operator\nspec:\n  resources:\n  - group: webhosting.timebertt.dev\n    resource: websites\n    controlledResources:\n    - group: apps\n      resource: deployments\n    - group: \"\"\n      resource: configmaps\n    - group: \"\"\n      resource: services\n    - group: networking.k8s.io\n      resource: ingresses\n  namespaceSelector:\n    matchLabels:\n      webhosting.timebertt.dev/project: \"true\"\n"
  },
  {
    "path": "webhosting-operator/config/manager/controllerring/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1alpha1\nkind: Component\n\nresources:\n- controllerring.yaml\n- sharder_rbac.yaml\n\npatches:\n- path: manager_patch.yaml\n"
  },
  {
    "path": "webhosting-operator/config/manager/controllerring/manager_patch.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: operator\n  namespace: system\nspec:\n  template:\n    spec:\n      containers:\n      - name: manager\n        env:\n        - name: ENABLE_SHARDING\n          value: \"true\"\n"
  },
  {
    "path": "webhosting-operator/config/manager/controllerring/sharder_rbac.yaml",
    "content": "# These manifests grant the sharder controller permissions to act on resources that we listed in the ControllerRing.\n# We need to grant these permissions explicitly depending on what we configured. Otherwise, the sharder would require\n# cluster-admin access.\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: sharding:controllerring:webhosting-operator\nrules:\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - websites\n  verbs:\n  - list\n  - patch\n- apiGroups:\n  - apps\n  resources:\n  - deployments\n  verbs:\n  - list\n  - patch\n- apiGroups:\n  - \"\"\n  resources:\n  - configmaps\n  - services\n  verbs:\n  - list\n  - patch\n- apiGroups:\n  - networking.k8s.io\n  resources:\n  - ingresses\n  verbs:\n  - list\n  - patch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: sharding:controllerring:webhosting-operator\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: sharding:controllerring:webhosting-operator\nsubjects:\n- kind: ServiceAccount\n  name: sharder\n  namespace: sharding-system\n"
  },
  {
    "path": "webhosting-operator/config/manager/crds/kustomization.yaml",
    "content": "# This kustomization.yaml is not intended to be run by itself,\n# since it depends on service name and namespace that are out of this kustomize package.\n# It should be run by config/manager/default\nresources:\n- webhosting.timebertt.dev_websites.yaml\n- webhosting.timebertt.dev_themes.yaml\n#+kubebuilder:scaffold:crdkustomizeresource\n\n# the following config is for teaching kustomize how to do kustomization for CRDs.\nconfigurations:\n- kustomizeconfig.yaml\n"
  },
  {
    "path": "webhosting-operator/config/manager/crds/kustomizeconfig.yaml",
    "content": "# This file is for teaching kustomize how to substitute name and namespace reference in CRD\nnameReference:\n- kind: Service\n  version: v1\n  fieldSpecs:\n  - kind: CustomResourceDefinition\n    version: v1\n    group: apiextensions.k8s.io\n    path: spec/conversion/webhook/clientConfig/service/name\n\nnamespace:\n- kind: CustomResourceDefinition\n  version: v1\n  group: apiextensions.k8s.io\n  path: spec/conversion/webhook/clientConfig/service/namespace\n  create: false\n\nvarReference:\n- path: metadata/annotations\n"
  },
  {
    "path": "webhosting-operator/config/manager/crds/webhosting.timebertt.dev_themes.yaml",
    "content": "---\napiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.19.0\n  name: themes.webhosting.timebertt.dev\nspec:\n  group: webhosting.timebertt.dev\n  names:\n    kind: Theme\n    listKind: ThemeList\n    plural: themes\n    singular: theme\n  scope: Cluster\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .spec.color\n      name: Color\n      type: string\n    - jsonPath: .spec.fontFamily\n      name: Font Family\n      type: string\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1alpha1\n    schema:\n      openAPIV3Schema:\n        description: Theme is the Schema for the themes API.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec contains the specification of the desired behavior of\n              the Theme.\n            properties:\n              color:\n                description: Color is a CSS color for a Website.\n                type: string\n              fontFamily:\n                description: FontFamily is a font family for a Website.\n                type: string\n            required:\n            - color\n            - fontFamily\n            type: object\n          status:\n            description: Status contains the most recently observed status of the\n              Theme.\n            type: object\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n"
  },
  {
    "path": "webhosting-operator/config/manager/crds/webhosting.timebertt.dev_websites.yaml",
    "content": "---\napiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n  annotations:\n    controller-gen.kubebuilder.io/version: v0.19.0\n  name: websites.webhosting.timebertt.dev\nspec:\n  group: webhosting.timebertt.dev\n  names:\n    kind: Website\n    listKind: WebsiteList\n    plural: websites\n    singular: website\n  scope: Namespaced\n  versions:\n  - additionalPrinterColumns:\n    - jsonPath: .spec.theme\n      name: Theme\n      type: string\n    - jsonPath: .status.phase\n      name: Phase\n      type: string\n    - jsonPath: .status.lastTransitionTime\n      name: Since\n      type: date\n    - jsonPath: .metadata.creationTimestamp\n      name: Age\n      type: date\n    name: v1alpha1\n    schema:\n      openAPIV3Schema:\n        description: Website enables declarative management of hosted websites.\n        properties:\n          apiVersion:\n            description: |-\n              APIVersion defines the versioned schema of this representation of an object.\n              Servers should convert recognized schemas to the latest internal value, and\n              may reject unrecognized values.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources\n            type: string\n          kind:\n            description: |-\n              Kind is a string value representing the REST resource this object represents.\n              Servers may infer this from the endpoint the client submits requests to.\n              Cannot be updated.\n              In CamelCase.\n              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds\n            type: string\n          metadata:\n            type: object\n          spec:\n            description: Spec contains the specification of the desired behavior of\n              the Website.\n            properties:\n              theme:\n                description: Theme references a Theme object to be used for this Website.\n                type: string\n            required:\n            - theme\n            type: object\n          status:\n            description: Status contains the most recently observed status of the\n              Website.\n            properties:\n              lastTransitionTime:\n                description: LastTransitionTime is the last time the observedGeneration\n                  or phase transitioned from one value to another.\n                format: date-time\n                type: string\n              observedGeneration:\n                description: The generation observed by the Website controller.\n                format: int64\n                type: integer\n              phase:\n                description: Phase is the current phase of this Website.\n                type: string\n            type: object\n        type: object\n    served: true\n    storage: true\n    subresources:\n      status: {}\n"
  },
  {
    "path": "webhosting-operator/config/manager/devel/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1alpha1\nkind: Component\n\npatches:\n- target:\n    group: apps\n    kind: Deployment\n    name: webhosting-operator\n    namespace: webhosting-system\n  patch: |\n    - op: add\n      path: /spec/template/spec/containers/0/args/-\n      value: --zap-devel\n"
  },
  {
    "path": "webhosting-operator/config/manager/overlays/debug/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../../base\n\npatches:\n- path: manager_debug_patch.yaml\n"
  },
  {
    "path": "webhosting-operator/config/manager/overlays/debug/manager_debug_patch.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: operator\n  namespace: system\nspec:\n  strategy:\n    type: Recreate\n  template:\n    spec:\n      securityContext:\n        # delve can't run as non-root (when using skaffold debug)\n        runAsNonRoot: false\n      containers:\n      - name: manager\n        env:\n        # disable leader election for debugging and use Deployment strategy Recreate.\n        # other option would have been to increase the durations and rely on ReleaseOnCancel to release the lease,\n        # however the delve debugger seems to kill the child process too fast for the leader elector to release the lease\n        # (probably, this is because the network connection to the skaffold/dlv client breaks off during termination)\n        - name: LEADER_ELECT\n          value: \"false\"\n      terminationGracePeriodSeconds: 5\n"
  },
  {
    "path": "webhosting-operator/config/manager/overlays/default/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../../base\n\ncomponents:\n- ../../controllerring\n"
  },
  {
    "path": "webhosting-operator/config/manager/overlays/devel/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../default\n\ncomponents:\n- ../../devel\n"
  },
  {
    "path": "webhosting-operator/config/manager/overlays/non-sharded/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../../base\n\npatches:\n- path: manager_patch.yaml\n"
  },
  {
    "path": "webhosting-operator/config/manager/overlays/non-sharded/manager_patch.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: operator\n  namespace: system\nspec:\n  replicas: 1\n  template:\n    spec:\n      containers:\n      - name: manager\n        env:\n        - name: ENABLE_SHARDING\n          value: \"false\"\n        # When comparing singleton vs sharded setups, the singleton will fail to verify the SLOs because it has too few\n        # website workers. Increase the worker count to allow comparing the setups.\n        - name: WEBSITE_CONCURRENT_SYNCS\n          value: \"50\"\n"
  },
  {
    "path": "webhosting-operator/config/manager/overlays/non-sharded-devel/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../non-sharded\n\ncomponents:\n- ../../devel\n"
  },
  {
    "path": "webhosting-operator/config/manager/overlays/shoot/default/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../../default\n\ncomponents:\n- ../../../with-dns\n"
  },
  {
    "path": "webhosting-operator/config/manager/overlays/shoot/devel/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../default\n\ncomponents:\n- ../../../devel\n"
  },
  {
    "path": "webhosting-operator/config/manager/overlays/shoot/non-sharded/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../../non-sharded\n\ncomponents:\n- ../../../with-dns\n"
  },
  {
    "path": "webhosting-operator/config/manager/overlays/shoot/non-sharded-devel/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../non-sharded\n\ncomponents:\n- ../../../devel\n"
  },
  {
    "path": "webhosting-operator/config/manager/rbac/kustomization.yaml",
    "content": "resources:\n# All RBAC will be applied under this service account in\n# the deployment namespace. You may comment out this resource\n# if your manager will use a service account that exists at\n# runtime. Be sure to update RoleBinding and ClusterRoleBinding\n# subjects if changing service account names.\n- service_account.yaml\n- role.yaml\n- role_binding.yaml\n- leader_election_role.yaml\n- leader_election_role_binding.yaml\n# provide parca running in namespace \"parca\" with the permissions required for service discovery in namespace\n# \"webhosting-system\" and scrape the pprof endpoints of webhosting-operator\n- parca_rbac.yaml\n"
  },
  {
    "path": "webhosting-operator/config/manager/rbac/leader_election_role.yaml",
    "content": "# permissions to do leader election.\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  name: leader-election\nrules:\n- apiGroups:\n  - coordination.k8s.io\n  resources:\n  - leases\n  verbs:\n  - get\n  - list\n  - watch\n  - create\n  - update\n  - patch\n  - delete\n- apiGroups:\n  - \"\"\n  resources:\n  - events\n  verbs:\n  - create\n  - patch\n"
  },
  {
    "path": "webhosting-operator/config/manager/rbac/leader_election_role_binding.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: leader-election\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: leader-election\nsubjects:\n- kind: ServiceAccount\n  name: operator\n  namespace: system\n"
  },
  {
    "path": "webhosting-operator/config/manager/rbac/parca_rbac.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  name: parca-service-discovery\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - services\n  - endpoints\n  - pods\n  verbs:\n  - get\n  - list\n  - watch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  name: parca-service-discovery\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: parca-service-discovery\nsubjects:\n- kind: ServiceAccount\n  name: parca\n  namespace: parca\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: operator-pprof-reader\nrules:\n- nonResourceURLs:\n  - \"/debug/pprof/allocs\"\n  - \"/debug/pprof/block\"\n  - \"/debug/pprof/goroutine\"\n  - \"/debug/pprof/heap\"\n  - \"/debug/pprof/mutex\"\n  - \"/debug/pprof/profile\"\n  - \"/debug/pprof/symbol\"\n  - \"/debug/pprof/threadcreate\"\n  - \"/debug/pprof/trace\"\n  verbs:\n  - get\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: observability\n    app.kubernetes.io/instance: parca\n    app.kubernetes.io/name: parca\n  name: parca-pprof-reader\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: operator-pprof-reader\nsubjects:\n- kind: ServiceAccount\n  name: parca\n  namespace: parca\n"
  },
  {
    "path": "webhosting-operator/config/manager/rbac/role.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: operator\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - configmaps\n  - services\n  verbs:\n  - create\n  - get\n  - list\n  - patch\n  - watch\n- apiGroups:\n  - \"\"\n  resources:\n  - events\n  verbs:\n  - create\n  - patch\n- apiGroups:\n  - apps\n  resources:\n  - deployments\n  verbs:\n  - create\n  - get\n  - list\n  - patch\n  - watch\n- apiGroups:\n  - coordination.k8s.io\n  resources:\n  - leases\n  verbs:\n  - delete\n  - get\n  - list\n  - patch\n  - update\n  - watch\n- apiGroups:\n  - networking.k8s.io\n  resources:\n  - ingresses\n  verbs:\n  - create\n  - get\n  - list\n  - patch\n  - watch\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - themes\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - websites\n  verbs:\n  - create\n  - delete\n  - get\n  - list\n  - patch\n  - update\n  - watch\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - websites/finalizers\n  verbs:\n  - update\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - websites/status\n  verbs:\n  - get\n  - patch\n  - update\n"
  },
  {
    "path": "webhosting-operator/config/manager/rbac/role_binding.yaml",
    "content": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: operator\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: operator\nsubjects:\n- kind: ServiceAccount\n  name: operator\n  namespace: system\n"
  },
  {
    "path": "webhosting-operator/config/manager/rbac/service_account.yaml",
    "content": "apiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: operator\n  namespace: system\nautomountServiceAccountToken: false\n"
  },
  {
    "path": "webhosting-operator/config/manager/rbac/theme_editor_role.yaml",
    "content": "# permissions for end users to edit themes.\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: theme-editor-role\nrules:\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - themes\n  verbs:\n  - create\n  - delete\n  - get\n  - list\n  - patch\n  - update\n  - watch\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - themes/status\n  verbs:\n  - get\n"
  },
  {
    "path": "webhosting-operator/config/manager/rbac/theme_viewer_role.yaml",
    "content": "# permissions for end users to view themes.\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: theme-viewer-role\nrules:\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - themes\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - themes/status\n  verbs:\n  - get\n"
  },
  {
    "path": "webhosting-operator/config/manager/rbac/website_editor_role.yaml",
    "content": "# permissions for end users to edit websites.\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: website-editor-role\nrules:\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - websites\n  verbs:\n  - create\n  - delete\n  - get\n  - list\n  - patch\n  - update\n  - watch\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - websites/status\n  verbs:\n  - get\n"
  },
  {
    "path": "webhosting-operator/config/manager/rbac/website_viewer_role.yaml",
    "content": "# permissions for end users to view websites.\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n  name: website-viewer-role\nrules:\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - websites\n  verbs:\n  - get\n  - list\n  - watch\n- apiGroups:\n  - webhosting.timebertt.dev\n  resources:\n  - websites/status\n  verbs:\n  - get\n"
  },
  {
    "path": "webhosting-operator/config/manager/with-dns/config.yaml",
    "content": "apiVersion: config.webhosting.timebertt.dev/v1alpha1\nkind: WebhostingOperatorConfig\ningress:\n  hosts:\n  - webhosting.timebertt.dev\n  tls:\n  - hosts:\n    - webhosting.timebertt.dev\n"
  },
  {
    "path": "webhosting-operator/config/manager/with-dns/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1alpha1\nkind: Component\n\ngeneratorOptions:\n  disableNameSuffixHash: true\n\nconfigMapGenerator:\n- name: webhosting-operator\n  namespace: webhosting-system\n  files:\n  - config.yaml\n\npatches:\n- path: manager_patch.yaml\n- target:\n    group: apps\n    kind: Deployment\n    name: webhosting-operator\n    namespace: webhosting-system\n  patch: |\n    - op: add\n      path: /spec/template/spec/containers/0/args/-\n      value: --config=/config.yaml\n"
  },
  {
    "path": "webhosting-operator/config/manager/with-dns/manager_patch.yaml",
    "content": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: webhosting-operator\n  namespace: webhosting-system\nspec:\n  template:\n    spec:\n      containers:\n      - name: manager\n        volumeMounts:\n        - name: config\n          mountPath: /config.yaml\n          subPath: config.yaml\n      volumes:\n      - name: config\n        configMap:\n          name: webhosting-operator\n"
  },
  {
    "path": "webhosting-operator/config/monitoring/default/dashboards/experiments.json",
    "content": "{\n  \"annotations\": {\n    \"list\": [\n      {\n        \"builtIn\": 1,\n        \"datasource\": {\n          \"type\": \"grafana\",\n          \"uid\": \"-- Grafana --\"\n        },\n        \"enable\": true,\n        \"hide\": true,\n        \"iconColor\": \"rgba(0, 211, 255, 1)\",\n        \"name\": \"Annotations & Alerts\",\n        \"type\": \"dashboard\"\n      }\n    ]\n  },\n  \"editable\": true,\n  \"fiscalYearStartMonth\": 0,\n  \"graphTooltip\": 1,\n  \"id\": 35,\n  \"links\": [],\n  \"panels\": [\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 0\n      },\n      \"id\": 1,\n      \"panels\": [],\n      \"title\": \"Controller Load\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"P1809F7CD0C75ACF3\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\",\n            \"seriesBy\": \"last\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"axisSoftMax\": 10000,\n            \"axisSoftMin\": 0,\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              }\n            ]\n          },\n          \"unit\": \"short\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 1\n      },\n      \"id\": 2,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"P1809F7CD0C75ACF3\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"sum(namespace_run:kube_website_info:sum{run_id=~\\\"$run_id\\\"}) by (run_id)\",\n          \"legendFormat\": \"__auto\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Website Count\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"P1809F7CD0C75ACF3\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"normal\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 1\n      },\n      \"id\": 3,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"lastNotNull\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"right\",\n          \"showLegend\": true,\n          \"sortBy\": \"Last *\",\n          \"sortDesc\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"P1809F7CD0C75ACF3\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"sum(\\n    rate(controller_runtime_reconcile_total{\\n        job=\\\"experiment\\\", run_id=~\\\"$run_id\\\",\\n        controller=~\\\"website-(generator|deleter|mutator)\\\",\\n        result!=\\\"error\\\",\\n    }[$__rate_interval])\\n) by (controller)\",\n          \"legendFormat\": \"__auto\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Website Churn\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 9\n      },\n      \"id\": 4,\n      \"panels\": [],\n      \"title\": \"Controller SLOs\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"P1809F7CD0C75ACF3\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"fixedColor\": \"text\",\n            \"mode\": \"palette-classic\",\n            \"seriesBy\": \"last\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"dashed+area\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 1\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 10\n      },\n      \"id\": 5,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true,\n          \"sortBy\": \"Last *\",\n          \"sortDesc\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"single\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"P1809F7CD0C75ACF3\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"histogram_quantile($percentile/100,\\n    sum by (run_id, le) (rate(\\n        workqueue_queue_duration_seconds_bucket{\\n            job=\\\"webhosting-operator\\\", name=\\\"website\\\", run_id=~\\\"$run_id\\\"\\n        }[1m]\\n    ))\\n)\",\n          \"legendFormat\": \"{{run_id}}-1m\",\n          \"range\": true,\n          \"refId\": \"A\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"P1809F7CD0C75ACF3\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"histogram_quantile($percentile/100,\\n    sum by (run_id, le) (rate(\\n        workqueue_queue_duration_seconds_bucket{\\n            job=\\\"webhosting-operator\\\", name=\\\"website\\\", run_id=~\\\"$run_id\\\"\\n        }[15m]\\n    ))\\n)\",\n          \"hide\": false,\n          \"legendFormat\": \"{{run_id}}-15m\",\n          \"range\": true,\n          \"refId\": \"B\"\n        }\n      ],\n      \"title\": \"Queue Latency (P$percentile)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"P1809F7CD0C75ACF3\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"fixedColor\": \"text\",\n            \"mode\": \"palette-classic\",\n            \"seriesBy\": \"last\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"log\": 2,\n              \"type\": \"log\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"dashed+area\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 5\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 10\n      },\n      \"id\": 6,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true,\n          \"sortBy\": \"Last *\",\n          \"sortDesc\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"single\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"P1809F7CD0C75ACF3\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"histogram_quantile($percentile/100,\\n    sum by (run_id, le) (rate(\\n        experiment_website_reconciliation_duration_seconds_bucket{\\n            job=\\\"experiment\\\", run_id=~\\\"$run_id\\\"\\n        }[1m]\\n    ))\\n)\",\n          \"legendFormat\": \"{{run_id}}-1m\",\n          \"range\": true,\n          \"refId\": \"A\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"P1809F7CD0C75ACF3\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"histogram_quantile($percentile/100,\\n    sum by (run_id, le) (rate(\\n        experiment_website_reconciliation_duration_seconds_bucket{\\n            job=\\\"experiment\\\", run_id=~\\\"$run_id\\\"\\n        }[15m]\\n    ))\\n)\",\n          \"hide\": false,\n          \"legendFormat\": \"{{run_id}}-15m\",\n          \"range\": true,\n          \"refId\": \"B\"\n        }\n      ],\n      \"title\": \"Reconciliation Latency (P$percentile)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 18\n      },\n      \"id\": 7,\n      \"panels\": [],\n      \"title\": \"Controller Resource Usage\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"P1809F7CD0C75ACF3\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"fixedColor\": \"text\",\n            \"mode\": \"palette-classic\",\n            \"seriesBy\": \"last\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"axisSoftMin\": 0,\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"normal\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              }\n            ]\n          },\n          \"unit\": \"cores\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 19\n      },\n      \"id\": 8,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"max\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"right\",\n          \"showLegend\": true,\n          \"sortBy\": \"Last *\",\n          \"sortDesc\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"P1809F7CD0C75ACF3\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"sum by (namespace, pod) (rate(\\n    container_cpu_usage_seconds_total{\\n        pod=~\\\"sharder-.+|webhosting-operator-.+\\\",\\n        container=~\\\"sharder|manager\\\"\\n    }[1m]\\n)) * on (namespace, pod) group_left (run_id) max by (namespace, pod, run_id) (kube_pod_labels{run_id=~\\\"$run_id\\\"})\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"CPU Usage by pod\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"P1809F7CD0C75ACF3\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"fixedColor\": \"text\",\n            \"mode\": \"palette-classic\",\n            \"seriesBy\": \"last\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"axisSoftMin\": 0,\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"normal\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              }\n            ]\n          },\n          \"unit\": \"bytes\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 27\n      },\n      \"id\": 9,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"max\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"right\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"P1809F7CD0C75ACF3\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"sum by (namespace, pod, run_id) (\\n    go_memory_classes_total_bytes{pod=~\\\"sharder-.+|webhosting-operator-.+\\\",run_id=~\\\"$run_id\\\"}\\n    - go_memory_classes_heap_released_bytes{\\n        pod=~\\\"sharder-.+|webhosting-operator-.+\\\",\\n        run_id=~\\\"$run_id\\\"\\n    }\\n    - go_memory_classes_heap_unused_bytes{\\n        pod=~\\\"sharder-.+|webhosting-operator-.+\\\",\\n        run_id=~\\\"$run_id\\\"\\n    }\\n    - go_memory_classes_heap_free_bytes{\\n        pod=~\\\"sharder-.+|webhosting-operator-.+\\\",\\n        run_id=~\\\"$run_id\\\"\\n    }\\n)\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Memory Usage by pod\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"P1809F7CD0C75ACF3\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"fixedColor\": \"text\",\n            \"mode\": \"palette-classic\",\n            \"seriesBy\": \"last\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"axisSoftMin\": 0,\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"normal\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              }\n            ]\n          },\n          \"unit\": \"binBps\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 35\n      },\n      \"id\": 10,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"max\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"right\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"P1809F7CD0C75ACF3\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"sum by (namespace, pod, run_id) (rate(\\n    container_network_receive_bytes_total{\\n        pod=~\\\"sharder-.+|webhosting-operator-.+\\\"\\n    }[1m]\\n)) * on (namespace, pod) group_left (run_id) max by (namespace, pod, run_id) (kube_pod_labels{run_id=~\\\"$run_id\\\"})\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Network Receive by pod\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"P1809F7CD0C75ACF3\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"fixedColor\": \"text\",\n            \"mode\": \"palette-classic\",\n            \"seriesBy\": \"last\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"axisSoftMin\": 0,\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 50,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"normal\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              }\n            ]\n          },\n          \"unit\": \"binBps\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 43\n      },\n      \"id\": 11,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"max\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"right\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"P1809F7CD0C75ACF3\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"sum by (namespace, pod, run_id) (rate(\\n    container_network_transmit_bytes_total{\\n        pod=~\\\"sharder-.+|webhosting-operator-.+\\\"\\n    }[1m]\\n)) * on (namespace, pod) group_left (run_id) max by (namespace, pod, run_id) (kube_pod_labels{run_id=~\\\"$run_id\\\"})\",\n          \"legendFormat\": \"{{pod}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Network Transmit by pod\",\n      \"type\": \"timeseries\"\n    }\n  ],\n  \"preload\": false,\n  \"refresh\": \"10s\",\n  \"schemaVersion\": 41,\n  \"tags\": [],\n  \"templating\": {\n    \"list\": [\n      {\n        \"allValue\": \".*\",\n        \"current\": {\n          \"text\": [\n            \"All\"\n          ],\n          \"value\": [\n            \"$__all\"\n          ]\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"P1809F7CD0C75ACF3\"\n        },\n        \"definition\": \"label_values(up{job=\\\"experiment\\\"},run_id)\",\n        \"includeAll\": true,\n        \"multi\": true,\n        \"name\": \"run_id\",\n        \"options\": [],\n        \"query\": {\n          \"qryType\": 1,\n          \"query\": \"label_values(up{job=\\\"experiment\\\"},run_id)\",\n          \"refId\": \"PrometheusVariableQueryEditor-VariableQuery\"\n        },\n        \"refresh\": 2,\n        \"regex\": \"\",\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"current\": {\n          \"text\": \"99\",\n          \"value\": \"99\"\n        },\n        \"label\": \"SLO Percentile\",\n        \"name\": \"percentile\",\n        \"options\": [\n          {\n            \"selected\": false,\n            \"text\": \"90\",\n            \"value\": \"90\"\n          },\n          {\n            \"selected\": false,\n            \"text\": \"95\",\n            \"value\": \"95\"\n          },\n          {\n            \"selected\": true,\n            \"text\": \"99\",\n            \"value\": \"99\"\n          }\n        ],\n        \"query\": \"90,95,99\",\n        \"type\": \"custom\"\n      }\n    ]\n  },\n  \"time\": {\n    \"from\": \"now-1h\",\n    \"to\": \"now\"\n  },\n  \"timepicker\": {},\n  \"timezone\": \"\",\n  \"title\": \"Experiments\",\n  \"uid\": \"d33509b4-7e28-41e2-961a-4d7fbad57d01\",\n  \"version\": 2\n}\n"
  },
  {
    "path": "webhosting-operator/config/monitoring/default/dashboards/sharding.json",
    "content": "{\n  \"annotations\": {\n    \"list\": [\n      {\n        \"builtIn\": 1,\n        \"datasource\": {\n          \"type\": \"grafana\",\n          \"uid\": \"-- Grafana --\"\n        },\n        \"enable\": true,\n        \"hide\": true,\n        \"iconColor\": \"rgba(0, 211, 255, 1)\",\n        \"name\": \"Annotations & Alerts\",\n        \"target\": {\n          \"limit\": 100,\n          \"matchAny\": false,\n          \"tags\": [],\n          \"type\": \"dashboard\"\n        },\n        \"type\": \"dashboard\"\n      }\n    ]\n  },\n  \"editable\": true,\n  \"fiscalYearStartMonth\": 0,\n  \"graphTooltip\": 1,\n  \"id\": 5,\n  \"links\": [],\n  \"panels\": [\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 0\n      },\n      \"id\": 6,\n      \"panels\": [],\n      \"title\": \"Headlines\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"default\": false,\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"max\": 10,\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          }\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 3,\n        \"x\": 0,\n        \"y\": 1\n      },\n      \"id\": 9,\n      \"options\": {\n        \"colorMode\": \"value\",\n        \"graphMode\": \"area\",\n        \"justifyMode\": \"auto\",\n        \"orientation\": \"auto\",\n        \"percentChangeColorMode\": \"standard\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"lastNotNull\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"showPercentChange\": false,\n        \"textMode\": \"auto\",\n        \"wideLayout\": true\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"max(max(controller_sharding_controllerring_status_available_shards{controllerring=\\\"$controllerring\\\"}) by(controllerring)) or vector(0)\",\n          \"hide\": false,\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Available Shards\",\n      \"type\": \"stat\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"max\": 10,\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          }\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 3,\n        \"x\": 3,\n        \"y\": 1\n      },\n      \"id\": 21,\n      \"options\": {\n        \"colorMode\": \"value\",\n        \"graphMode\": \"area\",\n        \"justifyMode\": \"auto\",\n        \"orientation\": \"auto\",\n        \"percentChangeColorMode\": \"standard\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"lastNotNull\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"showPercentChange\": false,\n        \"textMode\": \"auto\",\n        \"wideLayout\": true\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"max(max(controller_sharding_controllerring_status_shards{controllerring=\\\"$controllerring\\\"}) by(controllerring)) or vector(0)\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Total Shards\",\n      \"type\": \"stat\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 100,\n            \"gradientMode\": \"none\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineStyle\": {\n              \"fill\": \"solid\"\n            },\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"never\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"normal\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          }\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"dead\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"red\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"orphaned\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"#9f9f9f\",\n                  \"mode\": \"fixed\",\n                  \"seriesBy\": \"last\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"uncertain\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"#ffffff\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"unknown\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"purple\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"expired\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"yellow\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"ready\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"green\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 8,\n        \"x\": 6,\n        \"y\": 1\n      },\n      \"id\": 12,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"last\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"right\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(max(controller_sharding_shard_state{controllerring=\\\"$controllerring\\\"}) without(instance, pod)) by (state)\",\n          \"hide\": false,\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{shard}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Shards per State\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"red\"\n              },\n              {\n                \"color\": \"orange\",\n                \"value\": 70\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 80\n              },\n              {\n                \"color\": \"green\",\n                \"value\": 95\n              }\n            ]\n          },\n          \"unit\": \"percent\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 5,\n        \"x\": 14,\n        \"y\": 1\n      },\n      \"id\": 10,\n      \"options\": {\n        \"minVizHeight\": 75,\n        \"minVizWidth\": 75,\n        \"orientation\": \"auto\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"last\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"showThresholdLabels\": false,\n        \"showThresholdMarkers\": true,\n        \"sizing\": \"auto\"\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"(max(max(controller_sharding_controllerring_status_available_shards{controllerring=\\\"$controllerring\\\"}) by(controllerring)) or vector(0)) / (max(max(controller_sharding_controllerring_status_shards{controllerring=\\\"$controllerring\\\"}) by(controllerring)) or vector(0)) * 100\",\n          \"instant\": true,\n          \"range\": false,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Shard Readiness\",\n      \"type\": \"gauge\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"fixedColor\": \"green\",\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            }\n          },\n          \"mappings\": [],\n          \"max\": 100,\n          \"min\": 0,\n          \"unit\": \"percentunit\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 5,\n        \"x\": 19,\n        \"y\": 1\n      },\n      \"id\": 16,\n      \"options\": {\n        \"legend\": {\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": false\n        },\n        \"pieType\": \"pie\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"lastNotNull\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(namespace_shard:kube_website_shard:sum{namespace=~\\\"$project\\\",shard!=\\\"\\\"} or 0*max(controller_sharding_shard_info{controllerring=\\\"$controllerring\\\"}) by (shard)) by (shard) / ignoring(shard) group_left sum(namespace_shard:kube_website_shard:sum{namespace=~\\\"$project\\\"}) or vector(0)\",\n          \"instant\": true,\n          \"legendFormat\": \"__auto\",\n          \"range\": false,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Object Distribution\",\n      \"type\": \"piechart\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 7\n      },\n      \"id\": 2,\n      \"panels\": [],\n      \"title\": \"Object Distribution\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 100,\n            \"gradientMode\": \"none\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineStyle\": {\n              \"fill\": \"solid\"\n            },\n            \"lineWidth\": 1,\n            \"pointSize\": 4,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"never\",\n            \"spanNulls\": true,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"normal\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          },\n          \"unit\": \"short\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 11,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 8\n      },\n      \"id\": 8,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"max\",\n            \"last\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(namespace_shard:kube_website_shard:sum{namespace=~\\\"$project\\\",shard!=\\\"\\\"} or 0*max(controller_sharding_shard_info{controllerring=\\\"$controllerring\\\"}) by (shard)) by (shard)\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{shard}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Websites Count per Shard\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 100,\n            \"gradientMode\": \"none\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"never\",\n            \"spanNulls\": true,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"normal\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"decimals\": 0,\n          \"mappings\": [],\n          \"max\": 1,\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          },\n          \"unit\": \"percentunit\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 11,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 8\n      },\n      \"id\": 11,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"mean\",\n            \"last\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(namespace_shard:kube_website_shard:sum{namespace=~\\\"$project\\\",shard!=\\\"\\\"} or 0*max(controller_sharding_shard_info{controllerring=\\\"$controllerring\\\"}) by (shard)) by (shard) / ignoring(shard) group_left sum(namespace_shard:kube_website_shard:sum{namespace=~\\\"$project\\\"})\",\n          \"format\": \"time_series\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{shard}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Websites Percentage per Shard\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 100,\n            \"gradientMode\": \"none\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineStyle\": {\n              \"fill\": \"solid\"\n            },\n            \"lineWidth\": 1,\n            \"pointSize\": 4,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"never\",\n            \"spanNulls\": true,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"normal\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          },\n          \"unit\": \"short\"\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Unassigned\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"red\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Draining\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"yellow\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Assigned\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"green\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Assigned to unready\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"orange\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 19\n      },\n      \"id\": 15,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"max\",\n            \"last\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"right\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(namespace_shard_drain:kube_website_shard:sum{namespace=~\\\"$project\\\",shard!=\\\"\\\",drain=\\\"\\\"} * on(shard) group_left max(controller_sharding_shard_state{controllerring=\\\"$controllerring\\\",state=\\\"ready\\\"}) without(instance,pod)) or vector(0)\",\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"Assigned\",\n          \"range\": true,\n          \"refId\": \"A\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(namespace_shard_drain:kube_website_shard:sum{namespace=~\\\"$project\\\",shard!=\\\"\\\",drain=\\\"\\\"} * on(shard) group_left max(kube_shard_state{controllerring=\\\"$controllerring\\\",state!=\\\"ready\\\"}) by (shard)) or vector(0)\",\n          \"hide\": false,\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"Assigned to unready\",\n          \"range\": true,\n          \"refId\": \"B\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(namespace_shard_drain:kube_website_shard:sum{namespace=~\\\"$project\\\",drain!=\\\"\\\"}) or vector(0)\",\n          \"hide\": false,\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"Draining\",\n          \"range\": true,\n          \"refId\": \"C\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"sum(namespace_shard_drain:kube_website_shard:sum{namespace=~\\\"$project\\\",shard=\\\"\\\"}) or vector(0)\",\n          \"hide\": false,\n          \"instant\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"Unassigned\",\n          \"range\": true,\n          \"refId\": \"D\"\n        }\n      ],\n      \"title\": \"Websites Count per Sharding State\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 27\n      },\n      \"id\": 18,\n      \"panels\": [],\n      \"title\": \"Sharder\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"default\": false,\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 100,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineStyle\": {\n              \"fill\": \"solid\"\n            },\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 28\n      },\n      \"id\": 14,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(controller_sharding_assignments_total{controllerring=\\\"$controllerring\\\",  group=~\\\"$group\\\", resource=~\\\"$resource\\\"}[$__rate_interval])) or vector(0)\",\n          \"hide\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"Assignments\",\n          \"range\": true,\n          \"refId\": \"A\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(controller_sharding_movements_total{controllerring=\\\"$controllerring\\\", group=~\\\"$group\\\", resource=~\\\"$resource\\\"}[$__rate_interval])) or vector(0)\",\n          \"hide\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"Movements\",\n          \"range\": true,\n          \"refId\": \"B\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(controller_sharding_drains_total{controllerring=\\\"$controllerring\\\", group=~\\\"$group\\\", resource=~\\\"$resource\\\"}[$__rate_interval])) or vector(0)\",\n          \"hide\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"Drains\",\n          \"range\": true,\n          \"refId\": \"C\"\n        }\n      ],\n      \"title\": \"Sharder Actions\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"default\": false,\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 100,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineStyle\": {\n              \"fill\": \"solid\"\n            },\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 28\n      },\n      \"id\": 19,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"right\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(controller_sharding_assignments_total{controllerring=\\\"$controllerring\\\", group=~\\\"$group\\\", resource=~\\\"$resource\\\"}[$__rate_interval])) by (resource)\",\n          \"hide\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"{{kind}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Sharder Assignments by resource\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"default\": false,\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 100,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineStyle\": {\n              \"fill\": \"solid\"\n            },\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              }\n            ]\n          },\n          \"unit\": \"reqps\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 36\n      },\n      \"id\": 22,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(controller_runtime_webhook_requests_total{job=\\\"sharder\\\", webhook=\\\"/webhooks/sharder/\\\"}[$__rate_interval])) by (code)\",\n          \"hide\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"__auto\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Sharder Webhook Requests by code\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 100,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineStyle\": {\n              \"fill\": \"solid\"\n            },\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              }\n            ]\n          },\n          \"unit\": \"s\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 36\n      },\n      \"id\": 23,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"histogram_quantile(0.9, sum(rate(controller_runtime_webhook_latency_seconds_bucket{job=\\\"sharder\\\", webhook=\\\"/webhooks/sharder/\\\"}[$__rate_interval])) by (le))\",\n          \"hide\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"P90\",\n          \"range\": true,\n          \"refId\": \"A\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"histogram_quantile(0.95, sum(rate(controller_runtime_webhook_latency_seconds_bucket{job=\\\"sharder\\\", webhook=\\\"/webhooks/sharder/\\\"}[$__rate_interval])) by (le))\",\n          \"hide\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"P95\",\n          \"range\": true,\n          \"refId\": \"B\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"histogram_quantile(0.99, sum(rate(controller_runtime_webhook_latency_seconds_bucket{job=\\\"sharder\\\", webhook=\\\"/webhooks/sharder/\\\"}[$__rate_interval])) by (le))\",\n          \"hide\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"P99\",\n          \"range\": true,\n          \"refId\": \"C\"\n        }\n      ],\n      \"title\": \"Sharder Webhook Latency\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"barWidthFactor\": 0.6,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 100,\n            \"gradientMode\": \"opacity\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineStyle\": {\n              \"fill\": \"solid\"\n            },\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\"\n              }\n            ]\n          },\n          \"unit\": \"ops\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 44\n      },\n      \"id\": 20,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [],\n          \"displayMode\": \"list\",\n          \"placement\": \"right\",\n          \"showLegend\": false\n        },\n        \"tooltip\": {\n          \"hideZeros\": false,\n          \"mode\": \"single\",\n          \"sort\": \"none\"\n        }\n      },\n      \"pluginVersion\": \"12.0.1\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(rate(controller_sharding_ring_calculations_total{controllerring=\\\"$controllerring\\\"}[$__rate_interval]))\",\n          \"hide\": false,\n          \"interval\": \"\",\n          \"legendFormat\": \"Ring Calculations\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Sharder Ring Calculations\",\n      \"type\": \"timeseries\"\n    }\n  ],\n  \"preload\": false,\n  \"refresh\": \"10s\",\n  \"schemaVersion\": 41,\n  \"tags\": [\n    \"webhosting-operator\"\n  ],\n  \"templating\": {\n    \"list\": [\n      {\n        \"current\": {\n          \"text\": \"prometheus\",\n          \"value\": \"P1809F7CD0C75ACF3\"\n        },\n        \"includeAll\": false,\n        \"name\": \"datasource\",\n        \"options\": [],\n        \"query\": \"prometheus\",\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"type\": \"datasource\"\n      },\n      {\n        \"allValue\": \".*\",\n        \"current\": {\n          \"text\": \"webhosting-operator\",\n          \"value\": \"webhosting-operator\"\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(controller_sharding_controllerring_metadata_generation,controllerring)\",\n        \"includeAll\": false,\n        \"name\": \"controllerring\",\n        \"options\": [],\n        \"query\": {\n          \"qryType\": 1,\n          \"query\": \"label_values(controller_sharding_controllerring_metadata_generation,controllerring)\",\n          \"refId\": \"PrometheusVariableQueryEditor-VariableQuery\"\n        },\n        \"refresh\": 2,\n        \"regex\": \"\",\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"allValue\": \".*\",\n        \"current\": {\n          \"text\": [\n            \"All\"\n          ],\n          \"value\": [\n            \"$__all\"\n          ]\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(controller_sharding_assignments_total{controllerring=\\\"$controllerring\\\"},group)\",\n        \"includeAll\": true,\n        \"multi\": true,\n        \"name\": \"group\",\n        \"options\": [],\n        \"query\": {\n          \"qryType\": 1,\n          \"query\": \"label_values(controller_sharding_assignments_total{controllerring=\\\"$controllerring\\\"},group)\",\n          \"refId\": \"PrometheusVariableQueryEditor-VariableQuery\"\n        },\n        \"refresh\": 2,\n        \"regex\": \"\",\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"allValue\": \".*\",\n        \"current\": {\n          \"text\": [\n            \"All\"\n          ],\n          \"value\": [\n            \"$__all\"\n          ]\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(controller_sharding_assignments_total{controllerring=\\\"$controllerring\\\", group=~\\\"$group\\\"},resource)\",\n        \"includeAll\": true,\n        \"multi\": true,\n        \"name\": \"resource\",\n        \"options\": [],\n        \"query\": {\n          \"qryType\": 1,\n          \"query\": \"label_values(controller_sharding_assignments_total{controllerring=\\\"$controllerring\\\", group=~\\\"$group\\\"},resource)\",\n          \"refId\": \"PrometheusVariableQueryEditor-VariableQuery\"\n        },\n        \"refresh\": 2,\n        \"regex\": \"\",\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"allValue\": \".*\",\n        \"current\": {\n          \"text\": [\n            \"All\"\n          ],\n          \"value\": [\n            \"$__all\"\n          ]\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(kube_namespace_status_phase{job=\\\"kube-state-metrics\\\", namespace=~\\\"project-.+\\\"},namespace)\",\n        \"includeAll\": true,\n        \"multi\": true,\n        \"name\": \"project\",\n        \"options\": [],\n        \"query\": {\n          \"query\": \"label_values(kube_namespace_status_phase{job=\\\"kube-state-metrics\\\", namespace=~\\\"project-.+\\\"}, namespace)\",\n          \"refId\": \"StandardVariableQuery\"\n        },\n        \"refresh\": 2,\n        \"regex\": \"\",\n        \"sort\": 1,\n        \"type\": \"query\"\n      }\n    ]\n  },\n  \"time\": {\n    \"from\": \"now-30m\",\n    \"to\": \"now\"\n  },\n  \"timepicker\": {},\n  \"timezone\": \"\",\n  \"title\": \"Sharding\",\n  \"uid\": \"7liIybkVk\",\n  \"version\": 1\n}\n"
  },
  {
    "path": "webhosting-operator/config/monitoring/default/dashboards/webhosting.json",
    "content": "{\n  \"annotations\": {\n    \"list\": [\n      {\n        \"builtIn\": 1,\n        \"datasource\": {\n          \"type\": \"datasource\",\n          \"uid\": \"grafana\"\n        },\n        \"enable\": true,\n        \"hide\": true,\n        \"iconColor\": \"rgba(0, 211, 255, 1)\",\n        \"name\": \"Annotations & Alerts\",\n        \"target\": {\n          \"limit\": 100,\n          \"matchAny\": false,\n          \"tags\": [],\n          \"type\": \"dashboard\"\n        },\n        \"type\": \"dashboard\"\n      }\n    ]\n  },\n  \"description\": \"Overview over Webhosting objects\",\n  \"editable\": true,\n  \"fiscalYearStartMonth\": 0,\n  \"graphTooltip\": 1,\n  \"links\": [],\n  \"liveNow\": true,\n  \"panels\": [\n    {\n      \"collapsed\": false,\n      \"datasource\": {\n        \"type\": \"datasource\",\n        \"uid\": \"grafana\"\n      },\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 0\n      },\n      \"id\": 6,\n      \"panels\": [],\n      \"title\": \"Headlines\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          }\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 5,\n        \"w\": 8,\n        \"x\": 0,\n        \"y\": 1\n      },\n      \"id\": 2,\n      \"options\": {\n        \"colorMode\": \"value\",\n        \"graphMode\": \"area\",\n        \"justifyMode\": \"auto\",\n        \"orientation\": \"auto\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"lastNotNull\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"textMode\": \"auto\"\n      },\n      \"pluginVersion\": \"9.5.3\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(namespace_run:kube_website_info:sum{namespace=~\\\"$project\\\"}) or vector(0)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Websites\",\n      \"type\": \"stat\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"percentage\",\n            \"steps\": [\n              {\n                \"color\": \"red\",\n                \"value\": null\n              },\n              {\n                \"color\": \"orange\",\n                \"value\": 80\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 90\n              },\n              {\n                \"color\": \"green\",\n                \"value\": 98\n              }\n            ]\n          },\n          \"unit\": \"percent\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 5,\n        \"w\": 6,\n        \"x\": 8,\n        \"y\": 1\n      },\n      \"id\": 12,\n      \"options\": {\n        \"orientation\": \"auto\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"last\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"showThresholdLabels\": false,\n        \"showThresholdMarkers\": true\n      },\n      \"pluginVersion\": \"9.5.3\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"(sum(namespace_phase:kube_website_status_phase:sum{namespace=~\\\"$project\\\",phase=\\\"Ready\\\"}) or vector(0)) / (sum(namespace_phase:kube_website_status_phase:sum{namespace=~\\\"$project\\\"}) or vector(0)) * 100\",\n          \"instant\": true,\n          \"interval\": \"\",\n          \"legendFormat\": \"\",\n          \"range\": false,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Website Readiness\",\n      \"type\": \"gauge\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          }\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 5,\n        \"w\": 5,\n        \"x\": 14,\n        \"y\": 1\n      },\n      \"id\": 8,\n      \"options\": {\n        \"colorMode\": \"value\",\n        \"graphMode\": \"area\",\n        \"justifyMode\": \"auto\",\n        \"orientation\": \"auto\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"lastNotNull\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"textMode\": \"auto\"\n      },\n      \"pluginVersion\": \"9.5.3\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(max(kube_theme_info) without (instance, pod)) or vector(0)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Themes\",\n      \"type\": \"stat\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          }\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 5,\n        \"w\": 5,\n        \"x\": 19,\n        \"y\": 1\n      },\n      \"id\": 7,\n      \"options\": {\n        \"colorMode\": \"value\",\n        \"graphMode\": \"area\",\n        \"justifyMode\": \"auto\",\n        \"orientation\": \"auto\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"lastNotNull\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"textMode\": \"auto\"\n      },\n      \"pluginVersion\": \"9.5.3\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(kube_namespace_status_phase{namespace=~\\\"project-.+\\\"}) or vector(0)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Projects\",\n      \"type\": \"stat\"\n    },\n    {\n      \"collapsed\": false,\n      \"datasource\": {\n        \"type\": \"datasource\",\n        \"uid\": \"grafana\"\n      },\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 6\n      },\n      \"id\": 4,\n      \"panels\": [],\n      \"title\": \"Details\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 100,\n            \"gradientMode\": \"none\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineStyle\": {\n              \"fill\": \"solid\"\n            },\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"normal\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          }\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 7\n      },\n      \"id\": 10,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"last\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"right\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(namespace_run:kube_website_info:sum{namespace=~\\\"$project\\\"} or 0*sum(kube_namespace_status_phase{namespace=~\\\"$project\\\"}) by (namespace)) by (namespace)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{namespace}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Websites per Project\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 100,\n            \"gradientMode\": \"none\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineStyle\": {\n              \"fill\": \"solid\"\n            },\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"normal\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 80\n              }\n            ]\n          }\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 7\n      },\n      \"id\": 13,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"last\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"right\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(sum(namespace_theme:kube_website_info:sum{namespace=~\\\"$project\\\"}) by (theme) or 0*max(kube_theme_info{}) by (theme)) by (theme)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{namespace}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Websites per Theme\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 100,\n            \"gradientMode\": \"none\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"lineInterpolation\": \"smooth\",\n            \"lineStyle\": {\n              \"fill\": \"solid\"\n            },\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"auto\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"normal\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"off\"\n            }\n          },\n          \"mappings\": [],\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          }\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Error\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"red\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Ready\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"green\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Pending\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"orange\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Terminating\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"color\",\n                \"value\": {\n                  \"fixedColor\": \"yellow\",\n                  \"mode\": \"fixed\"\n                }\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 15\n      },\n      \"id\": 14,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"last\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"right\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(namespace_phase:kube_website_status_phase:sum{namespace=~\\\"$project\\\"}) by (phase)\",\n          \"interval\": \"\",\n          \"legendFormat\": \"{{phase}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Websites per Phase\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"datasource\": {\n        \"type\": \"datasource\",\n        \"uid\": \"grafana\"\n      },\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 23\n      },\n      \"id\": 18,\n      \"panels\": [],\n      \"title\": \"Websites\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"P1809F7CD0C75ACF3\"\n      },\n      \"description\": \"\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"custom\": {\n            \"align\": \"auto\",\n            \"cellOptions\": {\n              \"type\": \"auto\"\n            },\n            \"inspect\": false\n          },\n          \"links\": [],\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          }\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"website\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"links\",\n                \"value\": [\n                  {\n                    \"targetBlank\": true,\n                    \"title\": \"Open Website\",\n                    \"url\": \"https://webhosting.timebertt.dev/${__data.fields.namespace}/${__data.fields.website}\"\n                  }\n                ]\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Value\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"custom.hidden\",\n                \"value\": true\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 12,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 24\n      },\n      \"id\": 19,\n      \"options\": {\n        \"cellHeight\": \"sm\",\n        \"footer\": {\n          \"countRows\": false,\n          \"fields\": \"\",\n          \"reducer\": [\n            \"sum\"\n          ],\n          \"show\": false\n        },\n        \"showHeader\": true\n      },\n      \"pluginVersion\": \"9.5.3\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"P1809F7CD0C75ACF3\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": true,\n          \"expr\": \"sum(kube_website_info{namespace=~\\\"$project\\\", website!~\\\"experiment-.+\\\"} * on(theme) group_left(color, font_family) max(kube_theme_info) without (instance, pod)) by (namespace, theme, website, color, font_family)\",\n          \"format\": \"table\",\n          \"instant\": true,\n          \"interval\": \"\",\n          \"legendFormat\": \"\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Website List\",\n      \"transformations\": [\n        {\n          \"id\": \"organize\",\n          \"options\": {\n            \"excludeByName\": {\n              \"Time\": true,\n              \"Value #A\": true\n            },\n            \"indexByName\": {\n              \"Time\": 0,\n              \"Value #A\": 6,\n              \"color\": 4,\n              \"font_family\": 5,\n              \"namespace\": 1,\n              \"theme\": 3,\n              \"website\": 2\n            },\n            \"renameByName\": {}\n          }\n        }\n      ],\n      \"type\": \"table\"\n    }\n  ],\n  \"refresh\": \"10s\",\n  \"schemaVersion\": 38,\n  \"style\": \"dark\",\n  \"tags\": [\n    \"webhosting-operator\"\n  ],\n  \"templating\": {\n    \"list\": [\n      {\n        \"current\": {\n          \"selected\": false,\n          \"text\": \"prometheus\",\n          \"value\": \"prometheus\"\n        },\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"multi\": false,\n        \"name\": \"datasource\",\n        \"options\": [],\n        \"query\": \"prometheus\",\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"type\": \"datasource\"\n      },\n      {\n        \"allValue\": \"project-.+\",\n        \"current\": {\n          \"selected\": true,\n          \"text\": [\n            \"All\"\n          ],\n          \"value\": [\n            \"$__all\"\n          ]\n        },\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(kube_namespace_status_phase{job=\\\"kube-state-metrics\\\", namespace=~\\\"project-.+\\\"}, namespace)\",\n        \"hide\": 0,\n        \"includeAll\": true,\n        \"multi\": true,\n        \"name\": \"project\",\n        \"options\": [],\n        \"query\": {\n          \"query\": \"label_values(kube_namespace_status_phase{job=\\\"kube-state-metrics\\\", namespace=~\\\"project-.+\\\"}, namespace)\",\n          \"refId\": \"StandardVariableQuery\"\n        },\n        \"refresh\": 2,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"sort\": 1,\n        \"type\": \"query\"\n      }\n    ]\n  },\n  \"time\": {\n    \"from\": \"now-1h\",\n    \"to\": \"now\"\n  },\n  \"timepicker\": {},\n  \"timezone\": \"\",\n  \"title\": \"Webhosting\",\n  \"uid\": \"NbmNpqEnk\",\n  \"version\": 1,\n  \"weekStart\": \"\"\n}\n"
  },
  {
    "path": "webhosting-operator/config/monitoring/default/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../webhosting-operator\n\ngeneratorOptions:\n  disableNameSuffixHash: true\n\nconfigMapGenerator:\n- files:\n  - dashboards/sharding.json\n  - dashboards/webhosting.json\n  - dashboards/experiments.json\n  name: grafana-dashboards-sharding\n  namespace: monitoring\n  options:\n    labels:\n      grafana_dashboard: \"true\"\n"
  },
  {
    "path": "webhosting-operator/config/monitoring/webhosting-operator/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nnamespace: webhosting-system\n\nlabels:\n- includeSelectors: true\n  pairs:\n    app.kubernetes.io/name: webhosting-operator\n\nresources:\n# provide prometheus running in namespace \"monitoring\" with the permissions required for service discovery in namespace\n# \"webhosting-system\"\n- prometheus_rbac.yaml\n- servicemonitor.yaml\n- prometheusrule.yaml\n"
  },
  {
    "path": "webhosting-operator/config/monitoring/webhosting-operator/prometheus_rbac.yaml",
    "content": "---\napiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n  name: prometheus-k8s\nrules:\n- apiGroups:\n  - \"\"\n  resources:\n  - services\n  - endpoints\n  - pods\n  verbs:\n  - get\n  - list\n  - watch\n---\napiVersion: rbac.authorization.k8s.io/v1\nkind: RoleBinding\nmetadata:\n  labels:\n    app.kubernetes.io/component: prometheus\n    app.kubernetes.io/instance: k8s\n    app.kubernetes.io/name: prometheus\n  name: prometheus-k8s\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: Role\n  name: prometheus-k8s\nsubjects:\n- kind: ServiceAccount\n  name: prometheus-k8s\n  namespace: monitoring\n"
  },
  {
    "path": "webhosting-operator/config/monitoring/webhosting-operator/prometheusrule.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: PrometheusRule\nmetadata:\n  name: webhosting-operator\nspec:\n  groups:\n  - name: webhosting-website.rules\n    rules:\n    - record: namespace_run:kube_website_info:sum\n      expr: sum by (namespace, run_id) (kube_website_info)\n    - record: namespace_theme:kube_website_info:sum\n      expr: sum by (namespace, theme) (kube_website_info)\n    - record: namespace_phase:kube_website_status_phase:sum\n      expr: sum by (namespace, phase) (kube_website_status_phase)\n    - record: namespace_shard:kube_website_shard:sum\n      expr: sum by (namespace, shard) (kube_website_shard)\n    - record: namespace_shard_drain:kube_website_shard:sum\n      expr: sum by (namespace, shard, drain) (kube_website_shard)\n"
  },
  {
    "path": "webhosting-operator/config/monitoring/webhosting-operator/servicemonitor.yaml",
    "content": "apiVersion: monitoring.coreos.com/v1\nkind: ServiceMonitor\nmetadata:\n  name: webhosting-operator\nspec:\n  endpoints:\n  - path: /metrics\n    port: metrics\n    scheme: https\n    bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token\n    honorLabels: true\n    interval: 10s\n    scrapeTimeout: 10s\n    tlsConfig:\n      insecureSkipVerify: true\n    relabelings:\n    - action: labelmap\n      regex: \"__meta_kubernetes_pod_label_label_prometheus_io_(.*)\"\n      replacement: \"${1}\"\n  jobLabel: app.kubernetes.io/name\n  selector:\n    matchLabels:\n      app.kubernetes.io/name: webhosting-operator\n"
  },
  {
    "path": "webhosting-operator/config/policy/experiment-scheduling.yaml",
    "content": "apiVersion: kyverno.io/v1\nkind: ClusterPolicy\nmetadata:\n  name: experiment-scheduling\nspec:\n  failurePolicy: Fail\n  rules:\n  # schedule experiment on dedicated worker pool for better isolation in load tests\n  - name: add-scheduling-constraints\n    match:\n      any:\n      - resources:\n          kinds:\n          - Pod\n          namespaces:\n          - experiment\n          selector:\n            matchLabels:\n              app.kubernetes.io/name: experiment\n          operations:\n          - CREATE\n    mutate:\n      patchesJson6902: |-\n        - op: add\n          path: \"/spec/tolerations/-\"\n          value: {\"key\":\"dedicated-for\",\"operator\":\"Equal\",\"value\":\"experiment\",\"effect\":\"NoSchedule\"}        \n        - op: add\n          path: \"/spec/affinity/nodeAffinity/requiredDuringSchedulingIgnoredDuringExecution/nodeSelectorTerms/-\"\n          value: {\"matchExpressions\": [{\"key\":\"dedicated-for\",\"operator\":\"In\",\"values\":[\"experiment\"]}]}        \n"
  },
  {
    "path": "webhosting-operator/config/policy/guaranteed-resources.yaml",
    "content": "apiVersion: kyverno.io/v1\nkind: ClusterPolicy\nmetadata:\n  name: guaranteed-resources\nspec:\n  failurePolicy: Fail\n  rules:\n  # set resource requests to limits to guarantee the resources during load test experiments\n  - name: guaranteed-resources\n    match:\n      any:\n      - resources:\n          kinds:\n          - Pod\n          namespaces:\n          - experiment\n          - sharding-system\n          - webhosting-system\n          selector:\n            matchExpressions:\n            - key: app.kubernetes.io/name\n              operator: In\n              values:\n              - experiment\n              - controller-sharding\n              - webhosting-operator\n          operations:\n          - CREATE\n    mutate:\n      foreach:\n      - list: request.object.spec.containers\n        patchStrategicMerge:\n          spec:\n            containers:\n            - (name): \"{{element.name}}\"\n              resources:\n                requests:\n                  cpu: \"{{element.resources.limits.cpu}}\"\n                  memory: \"{{element.resources.limits.memory}}\"\n"
  },
  {
    "path": "webhosting-operator/config/policy/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- experiment-scheduling.yaml\n- scale-up-worker-experiment.yaml\n- webhosting-operator-scheduling.yaml\n- guaranteed-resources.yaml\n\nimages:\n- name: pause\n  newName: registry.k8s.io/pause\n  newTag: \"3.10\"\n"
  },
  {
    "path": "webhosting-operator/config/policy/scale-up-worker-experiment.yaml",
    "content": "---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  labels:\n    app: scale-up-worker\n    pool: experiment\n  name: scale-up-worker-experiment\n  namespace: default\nspec:\n  revisionHistoryLimit: 2\n  selector:\n    matchLabels:\n      app: scale-up-worker\n      pool: experiment\n  template:\n    metadata:\n      labels:\n        app: scale-up-worker\n        pool: experiment\n    spec:\n      containers:\n      - name: pause\n        image: pause\n      priorityClassName: reserve-excess-capacity\n      tolerations:\n      - key: dedicated-for\n        value: experiment\n        effect: NoSchedule\n      affinity:\n        nodeAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n            nodeSelectorTerms:\n            - matchExpressions:\n              - key: dedicated-for\n                operator: In\n                values:\n                - experiment\n        podAntiAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n          - labelSelector:\n              matchLabels:\n                app: scale-up-worker\n                pool: experiment\n            topologyKey: kubernetes.io/hostname\n---\napiVersion: scheduling.k8s.io/v1\nkind: PriorityClass\nmetadata:\n  name: reserve-excess-capacity\ndescription: PriorityClass for reserving excess capacity (over-provisioning)\nvalue: -5\n"
  },
  {
    "path": "webhosting-operator/config/policy/webhosting-operator-scheduling.yaml",
    "content": "apiVersion: kyverno.io/v1\nkind: ClusterPolicy\nmetadata:\n  name: webhosting-operator-scheduling\nspec:\n  failurePolicy: Fail\n  rules:\n  # schedule webhosting-operator on dedicated worker pool for better isolation in load tests\n  - name: add-scheduling-constraints\n    match:\n      any:\n      - resources:\n          kinds:\n          - Pod\n          namespaces:\n          - webhosting-system\n          selector:\n            matchLabels:\n              app.kubernetes.io/name: webhosting-operator\n          operations:\n          - CREATE\n    mutate:\n      patchesJson6902: |-\n        - op: add\n          path: \"/spec/tolerations/-\"\n          value: {\"key\":\"dedicated-for\",\"operator\":\"Equal\",\"value\":\"sharding\",\"effect\":\"NoSchedule\"}        \n        - op: add\n          path: \"/spec/affinity/nodeAffinity/requiredDuringSchedulingIgnoredDuringExecution/nodeSelectorTerms/-\"\n          value: {\"matchExpressions\": [{\"key\":\"dedicated-for\",\"operator\":\"In\",\"values\":[\"sharding\"]}]}        \n"
  },
  {
    "path": "webhosting-operator/config/samples/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- project_namespace.yaml\n- theme_exciting.yaml\n- theme_lame.yaml\n- website_kubecon.yaml\n- website_library.yaml\n"
  },
  {
    "path": "webhosting-operator/config/samples/project_namespace.yaml",
    "content": "apiVersion: v1\nkind: Namespace\nmetadata:\n  name: project-foo\n  labels:\n    webhosting.timebertt.dev/project: \"true\"\n"
  },
  {
    "path": "webhosting-operator/config/samples/theme_exciting.yaml",
    "content": "apiVersion: webhosting.timebertt.dev/v1alpha1\nkind: Theme\nmetadata:\n  name: exciting\nspec:\n  color: darkcyan\n  fontFamily: Futura\n"
  },
  {
    "path": "webhosting-operator/config/samples/theme_lame.yaml",
    "content": "apiVersion: webhosting.timebertt.dev/v1alpha1\nkind: Theme\nmetadata:\n  name: lame\nspec:\n  color: darkgray\n  fontFamily: Times\n"
  },
  {
    "path": "webhosting-operator/config/samples/website_kubecon.yaml",
    "content": "apiVersion: webhosting.timebertt.dev/v1alpha1\nkind: Website\nmetadata:\n  name: kubecon\n  namespace: project-foo\nspec:\n  theme: exciting\n"
  },
  {
    "path": "webhosting-operator/config/samples/website_library.yaml",
    "content": "apiVersion: webhosting.timebertt.dev/v1alpha1\nkind: Website\nmetadata:\n  name: library\n  namespace: project-foo\nspec:\n  theme: lame\n"
  },
  {
    "path": "webhosting-operator/config/samples/website_museum.yaml",
    "content": "apiVersion: webhosting.timebertt.dev/v1alpha1\nkind: Website\nmetadata:\n  name: museum\n  namespace: project-foo\nspec:\n  theme: lame\n"
  },
  {
    "path": "webhosting-operator/go.mod",
    "content": "module github.com/timebertt/kubernetes-controller-sharding/webhosting-operator\n\ngo 1.24.0\n\ntoolchain go1.25.7\n\nrequire (\n\tgithub.com/go-logr/logr v1.4.3\n\tgithub.com/hashicorp/go-multierror v1.1.1\n\tgithub.com/onsi/ginkgo/v2 v2.28.1\n\tgithub.com/onsi/gomega v1.39.1\n\tgithub.com/prometheus/client_golang v1.23.2\n\tgithub.com/prometheus/common v0.67.5\n\tgithub.com/spf13/cobra v1.10.2\n\tgithub.com/timebertt/kubernetes-controller-sharding v0.0.0\n\tgo.uber.org/zap v1.27.1\n\tgolang.org/x/time v0.14.0\n\tgopkg.in/yaml.v3 v3.0.1\n\tk8s.io/api v0.34.4\n\tk8s.io/apimachinery v0.34.4\n\tk8s.io/client-go v0.34.4\n\tk8s.io/component-base v0.34.4\n\tk8s.io/klog/v2 v2.130.1\n\tk8s.io/utils v0.0.0-20260210185600-b8788abfbbc2\n\tsigs.k8s.io/controller-runtime v0.22.5\n)\n\nreplace github.com/timebertt/kubernetes-controller-sharding => ../\n\nrequire (\n\tcel.dev/expr v0.24.0 // indirect\n\tgithub.com/Masterminds/semver/v3 v3.4.0 // indirect\n\tgithub.com/antlr4-go/antlr/v4 v4.13.0 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/blang/semver/v4 v4.0.0 // indirect\n\tgithub.com/cenkalti/backoff/v4 v4.3.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/emicklei/go-restful/v3 v3.12.2 // indirect\n\tgithub.com/evanphx/json-patch/v5 v5.9.11 // indirect\n\tgithub.com/felixge/httpsnoop v1.0.4 // indirect\n\tgithub.com/fsnotify/fsnotify v1.9.0 // indirect\n\tgithub.com/fxamacker/cbor/v2 v2.9.0 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/go-logr/zapr v1.3.0 // indirect\n\tgithub.com/go-openapi/jsonpointer v0.21.0 // indirect\n\tgithub.com/go-openapi/jsonreference v0.20.2 // indirect\n\tgithub.com/go-openapi/swag v0.23.0 // indirect\n\tgithub.com/go-task/slim-sprig/v3 v3.0.0 // indirect\n\tgithub.com/gogo/protobuf v1.3.2 // indirect\n\tgithub.com/google/btree v1.1.3 // indirect\n\tgithub.com/google/cel-go v0.26.0 // indirect\n\tgithub.com/google/gnostic-models v0.7.0 // indirect\n\tgithub.com/google/go-cmp v0.7.0 // indirect\n\tgithub.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect\n\tgithub.com/hashicorp/errwrap v1.1.0 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/josharian/intern v1.0.0 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/mailru/easyjson v0.7.7 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/pkg/errors v0.9.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/prometheus/client_model v0.6.2 // indirect\n\tgithub.com/prometheus/procfs v0.16.1 // indirect\n\tgithub.com/spf13/pflag v1.0.10 // indirect\n\tgithub.com/stoewer/go-strcase v1.3.0 // indirect\n\tgithub.com/x448/float16 v0.8.4 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.1.0 // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect\n\tgo.opentelemetry.io/otel v1.35.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.35.0 // indirect\n\tgo.opentelemetry.io/otel/sdk v1.34.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.35.0 // indirect\n\tgo.opentelemetry.io/proto/otlp v1.5.0 // indirect\n\tgo.uber.org/multierr v1.11.0 // indirect\n\tgo.yaml.in/yaml/v2 v2.4.3 // indirect\n\tgo.yaml.in/yaml/v3 v3.0.4 // indirect\n\tgolang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect\n\tgolang.org/x/mod v0.32.0 // indirect\n\tgolang.org/x/net v0.49.0 // indirect\n\tgolang.org/x/oauth2 v0.34.0 // indirect\n\tgolang.org/x/sync v0.19.0 // indirect\n\tgolang.org/x/sys v0.40.0 // indirect\n\tgolang.org/x/term v0.39.0 // indirect\n\tgolang.org/x/text v0.33.0 // indirect\n\tgolang.org/x/tools v0.41.0 // indirect\n\tgomodules.xyz/jsonpatch/v2 v2.5.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect\n\tgoogle.golang.org/grpc v1.72.1 // indirect\n\tgoogle.golang.org/protobuf v1.36.11 // indirect\n\tgopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect\n\tgopkg.in/inf.v0 v0.9.1 // indirect\n\tk8s.io/apiextensions-apiserver v0.34.3 // indirect\n\tk8s.io/apiserver v0.34.3 // indirect\n\tk8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect\n\tsigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect\n\tsigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect\n\tsigs.k8s.io/randfill v1.0.0 // indirect\n\tsigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect\n\tsigs.k8s.io/yaml v1.6.0 // indirect\n)\n"
  },
  {
    "path": "webhosting-operator/go.sum",
    "content": "cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=\ncel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=\ngithub.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=\ngithub.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=\ngithub.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=\ngithub.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=\ngithub.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=\ngithub.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=\ngithub.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=\ngithub.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=\ngithub.com/evanphx/json-patch v5.9.11+incompatible h1:ixHHqfcGvxhWkniF1tWxBHA0yb4Z+d1UQi45df52xW8=\ngithub.com/evanphx/json-patch v5.9.11+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=\ngithub.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=\ngithub.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=\ngithub.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=\ngithub.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=\ngithub.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=\ngithub.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=\ngithub.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=\ngithub.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=\ngithub.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=\ngithub.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=\ngithub.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE=\ngithub.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=\ngithub.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=\ngithub.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=\ngithub.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=\ngithub.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=\ngithub.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=\ngithub.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=\ngithub.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=\ngithub.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=\ngithub.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=\ngithub.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=\ngithub.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=\ngithub.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=\ngithub.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=\ngithub.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=\ngithub.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=\ngithub.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=\ngithub.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=\ngithub.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=\ngithub.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI=\ngithub.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=\ngithub.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=\ngithub.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=\ngithub.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=\ngithub.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=\ngithub.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=\ngithub.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=\ngithub.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=\ngithub.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=\ngithub.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=\ngithub.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=\ngithub.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung=\ngithub.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=\ngithub.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=\ngithub.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=\ngithub.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=\ngithub.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=\ngithub.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=\ngithub.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=\ngithub.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=\ngithub.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI=\ngithub.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE=\ngithub.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=\ngithub.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=\ngithub.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=\ngithub.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=\ngithub.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=\ngithub.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=\ngithub.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=\ngithub.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=\ngithub.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=\ngithub.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=\ngithub.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=\ngithub.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=\ngithub.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=\ngithub.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=\ngithub.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=\ngithub.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=\ngithub.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=\ngithub.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=\ngithub.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=\ngithub.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=\ngithub.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=\ngithub.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=\ngithub.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=\ngithub.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngo.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=\ngo.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=\ngo.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=\ngo.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=\ngo.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=\ngo.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=\ngo.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=\ngo.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=\ngo.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=\ngo.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=\ngo.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=\ngo.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=\ngo.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=\ngo.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=\ngo.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=\ngo.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=\ngo.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=\ngo.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=\ngo.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=\ngo.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=\ngo.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=\ngo.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=\ngo.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=\ngo.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=\ngolang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=\ngolang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=\ngolang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=\ngolang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=\ngolang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=\ngolang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=\ngolang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=\ngolang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=\ngolang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=\ngolang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=\ngolang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=\ngolang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=\ngomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=\ngoogle.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA=\ngoogle.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngoogle.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=\ngopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=\ngopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=\ngopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nk8s.io/api v0.34.4 h1:Z5hsoQcZ2yBjelb9j5JKzCVo9qv9XLkVm5llnqS4h+0=\nk8s.io/api v0.34.4/go.mod h1:6SaGYuGPkMqqCgg8rPG/OQoCrhgSEV+wWn9v21fDP3o=\nk8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g=\nk8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0=\nk8s.io/apimachinery v0.34.4 h1:C5SiSzLEMyWIk53sSbnk0WlOOyqv/MFnWvuc/d6M+xc=\nk8s.io/apimachinery v0.34.4/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=\nk8s.io/apiserver v0.34.3 h1:uGH1qpDvSiYG4HVFqc6A3L4CKiX+aBWDrrsxHYK0Bdo=\nk8s.io/apiserver v0.34.3/go.mod h1:QPnnahMO5C2m3lm6fPW3+JmyQbvHZQ8uudAu/493P2w=\nk8s.io/client-go v0.34.4 h1:IXhvzFdm0e897kXtLbeyMpAGzontcShJ/gi/XCCsOLc=\nk8s.io/client-go v0.34.4/go.mod h1:tXIVJTQabT5QRGlFdxZQFxrIhcGUPpKL5DAc4gSWTE8=\nk8s.io/component-base v0.34.4 h1:jP4XqR48YelfXIlRpOHQgms5GebU23zSE6xcvTwpXDE=\nk8s.io/component-base v0.34.4/go.mod h1:uujRfLNOwNiFWz47eBjNZEj/Swn2cdhqI7lW2MeFdrU=\nk8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=\nk8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=\nk8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=\nk8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=\nk8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=\nk8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=\nsigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM=\nsigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=\nsigs.k8s.io/controller-runtime v0.22.5 h1:v3nfSUMowX/2WMp27J9slwGFyAt7IV0YwBxAkrUr0GE=\nsigs.k8s.io/controller-runtime v0.22.5/go.mod h1:pc5SoYWnWI6I+cBHYYdZ7B6YHZVY5xNfll88JB+vniI=\nsigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=\nsigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=\nsigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=\nsigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=\nsigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=\nsigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=\nsigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=\nsigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/config/doc.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// +groupName=config.webhosting.timebertt.dev\n\npackage config // import \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/config\"\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/config/v1alpha1/defaults.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1\n\nimport (\n\t\"time\"\n\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/client-go/tools/leaderelection/resourcelock\"\n\tcomponentbaseconfigv1alpha1 \"k8s.io/component-base/config/v1alpha1\"\n\t\"k8s.io/utils/ptr\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n)\n\nfunc addDefaultingFuncs(scheme *runtime.Scheme) error {\n\treturn RegisterDefaults(scheme)\n}\n\nfunc SetDefaults_WebhostingOperatorConfig(obj *WebhostingOperatorConfig) {\n\tif obj.ClientConnection == nil {\n\t\tobj.ClientConnection = &componentbaseconfigv1alpha1.ClientConnectionConfiguration{}\n\t}\n\tif obj.LeaderElection == nil {\n\t\tobj.LeaderElection = &componentbaseconfigv1alpha1.LeaderElectionConfiguration{}\n\t}\n\tif obj.Debugging == nil {\n\t\tobj.Debugging = &componentbaseconfigv1alpha1.DebuggingConfiguration{}\n\t}\n\n\tif obj.GracefulShutdownTimeout == nil {\n\t\tvar defaultGracefulShutdownTimeout = 15 * time.Second\n\t\tobj.GracefulShutdownTimeout = &metav1.Duration{Duration: defaultGracefulShutdownTimeout}\n\t}\n}\n\nfunc SetDefaults_LeaderElectionConfiguration(obj *componentbaseconfigv1alpha1.LeaderElectionConfiguration) {\n\tif obj.ResourceLock == \"\" {\n\t\tobj.ResourceLock = resourcelock.LeasesResourceLock\n\t}\n\n\tcomponentbaseconfigv1alpha1.RecommendedDefaultLeaderElectionConfiguration(obj)\n\n\tif obj.ResourceName == \"\" {\n\t\tobj.ResourceName = webhostingv1alpha1.WebhostingOperatorName\n\t}\n\tif obj.ResourceNamespace == \"\" {\n\t\tobj.ResourceNamespace = webhostingv1alpha1.NamespaceSystem\n\t}\n}\n\nfunc SetDefaults_DebuggingConfiguration(obj *componentbaseconfigv1alpha1.DebuggingConfiguration) {\n\tcomponentbaseconfigv1alpha1.RecommendedDebuggingConfiguration(obj)\n\n\tif obj.EnableContentionProfiling == nil {\n\t\tobj.EnableContentionProfiling = ptr.To(false)\n\t}\n}\n\nfunc SetDefaults_HealthEndpoint(obj *HealthEndpoint) {\n\tif obj.BindAddress == \"\" {\n\t\tobj.BindAddress = \":8081\"\n\t}\n}\n\nfunc SetDefaults_MetricsEndpoint(obj *MetricsEndpoint) {\n\tif obj.BindAddress == \"\" {\n\t\tobj.BindAddress = \":8080\"\n\t}\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/config/v1alpha1/doc.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// +k8s:defaulter-gen=TypeMeta\n\npackage v1alpha1 // import \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/config/v1alpha1\"\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/config/v1alpha1/register.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package v1alpha1 contains API Schema definitions for the config v1alpha1 API group\n// +kubebuilder:object:generate=true\n// +groupName=config.webhosting.timebertt.dev\npackage v1alpha1\n\nimport (\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n)\n\n// GroupName is the group name used in this package.\nconst GroupName = \"config.webhosting.timebertt.dev\"\n\n// SchemeGroupVersion is group version used to register these objects\nvar SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: \"v1alpha1\"}\n\nvar (\n\t// SchemeBuilder is a new Scheme Builder which registers our API.\n\tSchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes, addDefaultingFuncs)\n\t// AddToScheme is a reference to the Scheme Builder's AddToScheme function.\n\tAddToScheme = SchemeBuilder.AddToScheme\n)\n\n// Adds the list of known types to the given scheme.\nfunc addKnownTypes(scheme *runtime.Scheme) error {\n\tscheme.AddKnownTypes(SchemeGroupVersion,\n\t\t&WebhostingOperatorConfig{},\n\t)\n\n\treturn nil\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/config/v1alpha1/types.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1\n\nimport (\n\tnetworkingv1 \"k8s.io/api/networking/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\tcomponentbaseconfigv1alpha1 \"k8s.io/component-base/config/v1alpha1\"\n)\n\n//+kubebuilder:object:root=true\n\n// WebhostingOperatorConfig is the Schema for the controllermanagerconfigs API\ntype WebhostingOperatorConfig struct {\n\tmetav1.TypeMeta `json:\",inline\"`\n\n\t// ClientConnection holds configuration for the kubernetes API clients.\n\t// +optional\n\tClientConnection *componentbaseconfigv1alpha1.ClientConnectionConfiguration `json:\"clientConnection,omitempty\"`\n\t// LeaderElection is the LeaderElection config to be used when configuring\n\t// the manager.Manager leader election\n\t// +optional\n\tLeaderElection *componentbaseconfigv1alpha1.LeaderElectionConfiguration `json:\"leaderElection,omitempty\"`\n\t// Debugging holds configuration for Debugging related features.\n\t// +optional\n\tDebugging *componentbaseconfigv1alpha1.DebuggingConfiguration `json:\"debugging,omitempty\"`\n\t// Health contains the controller health configuration\n\tHealth HealthEndpoint `json:\"health\"`\n\t// Metrics contains the controller metrics configuration\n\tMetrics MetricsEndpoint `json:\"metrics\"`\n\t// GracefulShutdownTimeout is the duration given to runnable to stop before the manager actually returns on stop.\n\t// To disable graceful shutdown, set it to 0s.\n\t// To use graceful shutdown without timeout, set to a negative duration, e.G. -1s.\n\t// The graceful shutdown is skipped for safety reasons in case the leader election lease is lost.\n\t// Defaults to 15s\n\tGracefulShutdownTimeout *metav1.Duration `json:\"gracefulShutDown,omitempty\"`\n\n\t// Ingress specifies configuration for the Ingress objects created for Websites.\n\t// +optional\n\tIngress *IngressConfiguration `json:\"ingress,omitempty\"`\n}\n\n// HealthEndpoint defines the health configs.\ntype HealthEndpoint struct {\n\t// BindAddress is the TCP address that the controller should bind to\n\t// for serving health probes\n\t// It can be set to \"0\" to disable serving the health probe.\n\t// Defaults to :8081\n\t// +optional\n\tBindAddress string `json:\"bindAddress,omitempty\"`\n}\n\n// MetricsEndpoint defines the metrics configs.\ntype MetricsEndpoint struct {\n\t// BindAddress is the TCP address that the controller should bind to\n\t// for serving prometheus metrics.\n\t// It can be set to \"0\" to disable the metrics serving.\n\t// Defaults to :8080\n\t// +optional\n\tBindAddress string `json:\"bindAddress,omitempty\"`\n}\n\n// IngressConfiguration contains configuration for the Ingress objects created for Websites.\ntype IngressConfiguration struct {\n\t// Annotations is a set of annotations to add to all created Ingress objects.\n\t// +optional\n\tAnnotations map[string]string `json:\"annotations,omitempty\"`\n\t// Hosts is a list of hosts, under which Websites shall be available.\n\t// +optional\n\tHosts []string `json:\"hosts,omitempty\"`\n\t// TLS configures TLS settings to be used on Ingress objects. Specify this to make Websites serve TLS connections for\n\t// the given hosts. SecretName is optional. If specified, the given Secret is expected to exist already in all project\n\t// namespaces. Otherwise, the Website controller will fill the Ingresses secretName field and expects the secret to be\n\t// created and filled by an external controller (e.g. cert-manager).\n\t// +optional\n\tTLS []networkingv1.IngressTLS `json:\"tls,omitempty\"`\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/config/v1alpha1/zz_generated.deepcopy.go",
    "content": "//go:build !ignore_autogenerated\n\n/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Code generated by controller-gen. DO NOT EDIT.\n\npackage v1alpha1\n\nimport (\n\tnetworkingv1 \"k8s.io/api/networking/v1\"\n\t\"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\tconfigv1alpha1 \"k8s.io/component-base/config/v1alpha1\"\n)\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *HealthEndpoint) DeepCopyInto(out *HealthEndpoint) {\n\t*out = *in\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthEndpoint.\nfunc (in *HealthEndpoint) DeepCopy() *HealthEndpoint {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(HealthEndpoint)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *IngressConfiguration) DeepCopyInto(out *IngressConfiguration) {\n\t*out = *in\n\tif in.Annotations != nil {\n\t\tin, out := &in.Annotations, &out.Annotations\n\t\t*out = make(map[string]string, len(*in))\n\t\tfor key, val := range *in {\n\t\t\t(*out)[key] = val\n\t\t}\n\t}\n\tif in.Hosts != nil {\n\t\tin, out := &in.Hosts, &out.Hosts\n\t\t*out = make([]string, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\tif in.TLS != nil {\n\t\tin, out := &in.TLS, &out.TLS\n\t\t*out = make([]networkingv1.IngressTLS, len(*in))\n\t\tfor i := range *in {\n\t\t\t(*in)[i].DeepCopyInto(&(*out)[i])\n\t\t}\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressConfiguration.\nfunc (in *IngressConfiguration) DeepCopy() *IngressConfiguration {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(IngressConfiguration)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *MetricsEndpoint) DeepCopyInto(out *MetricsEndpoint) {\n\t*out = *in\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsEndpoint.\nfunc (in *MetricsEndpoint) DeepCopy() *MetricsEndpoint {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(MetricsEndpoint)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *WebhostingOperatorConfig) DeepCopyInto(out *WebhostingOperatorConfig) {\n\t*out = *in\n\tout.TypeMeta = in.TypeMeta\n\tif in.ClientConnection != nil {\n\t\tin, out := &in.ClientConnection, &out.ClientConnection\n\t\t*out = new(configv1alpha1.ClientConnectionConfiguration)\n\t\t**out = **in\n\t}\n\tif in.LeaderElection != nil {\n\t\tin, out := &in.LeaderElection, &out.LeaderElection\n\t\t*out = new(configv1alpha1.LeaderElectionConfiguration)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n\tif in.Debugging != nil {\n\t\tin, out := &in.Debugging, &out.Debugging\n\t\t*out = new(configv1alpha1.DebuggingConfiguration)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n\tout.Health = in.Health\n\tout.Metrics = in.Metrics\n\tif in.GracefulShutdownTimeout != nil {\n\t\tin, out := &in.GracefulShutdownTimeout, &out.GracefulShutdownTimeout\n\t\t*out = new(v1.Duration)\n\t\t**out = **in\n\t}\n\tif in.Ingress != nil {\n\t\tin, out := &in.Ingress, &out.Ingress\n\t\t*out = new(IngressConfiguration)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhostingOperatorConfig.\nfunc (in *WebhostingOperatorConfig) DeepCopy() *WebhostingOperatorConfig {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(WebhostingOperatorConfig)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.\nfunc (in *WebhostingOperatorConfig) DeepCopyObject() runtime.Object {\n\tif c := in.DeepCopy(); c != nil {\n\t\treturn c\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/config/v1alpha1/zz_generated.defaults.go",
    "content": "//go:build !ignore_autogenerated\n// +build !ignore_autogenerated\n\n/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Code generated by defaulter-gen. DO NOT EDIT.\n\npackage v1alpha1\n\nimport (\n\truntime \"k8s.io/apimachinery/pkg/runtime\"\n)\n\n// RegisterDefaults adds defaulters functions to the given scheme.\n// Public to allow building arbitrary schemes.\n// All generated defaulters are covering - they call all nested defaulters.\nfunc RegisterDefaults(scheme *runtime.Scheme) error {\n\tscheme.AddTypeDefaultingFunc(&WebhostingOperatorConfig{}, func(obj interface{}) { SetObjectDefaults_WebhostingOperatorConfig(obj.(*WebhostingOperatorConfig)) })\n\treturn nil\n}\n\nfunc SetObjectDefaults_WebhostingOperatorConfig(in *WebhostingOperatorConfig) {\n\tSetDefaults_WebhostingOperatorConfig(in)\n\tif in.LeaderElection != nil {\n\t\tSetDefaults_LeaderElectionConfiguration(in.LeaderElection)\n\t}\n\tif in.Debugging != nil {\n\t\tSetDefaults_DebuggingConfiguration(in.Debugging)\n\t}\n\tSetDefaults_HealthEndpoint(&in.Health)\n\tSetDefaults_MetricsEndpoint(&in.Metrics)\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/webhosting/doc.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// +groupName=webhosting.timebertt.dev\n\npackage config // import \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting\"\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/webhosting/v1alpha1/constants.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1\n\nimport (\n\t\"k8s.io/apimachinery/pkg/labels\"\n)\n\nconst (\n\t// NamespaceSystem is the namespace where the webhosting-operator runs.\n\tNamespaceSystem = \"webhosting-system\"\n\t// WebhostingOperatorName is the name of the webhosting-operator Deployment, ControllerRing, etc.\n\tWebhostingOperatorName = \"webhosting-operator\"\n\t// LabelKeyProject is the label key on Namespaces for identifying webhosting projects.\n\tLabelKeyProject = \"webhosting.timebertt.dev/project\"\n\t// LabelValueProject is the label value for LabelKeyProject on Namespaces for identifying webhosting projects.\n\tLabelValueProject = \"true\"\n\n\t// LabelKeySkipWorkload is the label key on Websites for instructing webhosting-operator to skip any actual workload\n\t// for the website. Any value is accepted as truthy.\n\tLabelKeySkipWorkload = \"skip-workload\"\n)\n\nvar (\n\t// LabelSelectorProject is a selector for webhosting project namespaces.\n\tLabelSelectorProject = labels.SelectorFromSet(labels.Set{LabelKeyProject: LabelValueProject})\n)\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/webhosting/v1alpha1/doc.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1 // import \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/webhosting/v1alpha1/register.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package v1alpha1 contains API Schema definitions for the webhosting v1alpha1 API group\n// +kubebuilder:object:generate=true\n// +groupName=webhosting.timebertt.dev\npackage v1alpha1\n\nimport (\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n)\n\n// GroupName is the group name used in this package.\nconst GroupName = \"webhosting.timebertt.dev\"\n\n// SchemeGroupVersion is group version used to register these objects\nvar SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: \"v1alpha1\"}\n\nvar (\n\t// SchemeBuilder is a new Scheme Builder which registers our API.\n\tSchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)\n\t// AddToScheme is a reference to the Scheme Builder's AddToScheme function.\n\tAddToScheme = SchemeBuilder.AddToScheme\n)\n\n// Adds the list of known types to the given scheme.\nfunc addKnownTypes(scheme *runtime.Scheme) error {\n\tscheme.AddKnownTypes(SchemeGroupVersion,\n\t\t&Website{},\n\t\t&WebsiteList{},\n\t\t&Theme{},\n\t\t&ThemeList{},\n\t)\n\n\tmetav1.AddToGroupVersion(scheme, SchemeGroupVersion)\n\treturn nil\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/webhosting/v1alpha1/types_theme.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1\n\nimport (\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n)\n\n// ThemeSpec defines the desired state of a Theme.\ntype ThemeSpec struct {\n\t// Color is a CSS color for a Website.\n\tColor string `json:\"color\"`\n\t// FontFamily is a font family for a Website.\n\tFontFamily string `json:\"fontFamily\"`\n}\n\n// ThemeStatus defines the observed state of a Theme.\ntype ThemeStatus struct {\n}\n\n//+kubebuilder:object:root=true\n//+kubebuilder:subresource:status\n//+kubebuilder:resource:scope=Cluster\n//+kubebuilder:printcolumn:name=\"Color\",type=string,JSONPath=`.spec.color`\n//+kubebuilder:printcolumn:name=\"Font Family\",type=string,JSONPath=`.spec.fontFamily`\n//+kubebuilder:printcolumn:name=\"Age\",type=\"date\",JSONPath=\".metadata.creationTimestamp\"\n\n// Theme is the Schema for the themes API.\ntype Theme struct {\n\tmetav1.TypeMeta `json:\",inline\"`\n\t// Standard object's metadata.\n\t// +optional\n\tmetav1.ObjectMeta `json:\"metadata,omitempty\"`\n\t// Spec contains the specification of the desired behavior of the Theme.\n\t// +optional\n\tSpec ThemeSpec `json:\"spec,omitempty\"`\n\t// Status contains the most recently observed status of the Theme.\n\t// +optional\n\tStatus ThemeStatus `json:\"status,omitempty\"`\n}\n\n//+kubebuilder:object:root=true\n\n// ThemeList contains a list of Themes.\ntype ThemeList struct {\n\tmetav1.TypeMeta `json:\",inline\"`\n\t// Standard list metadata.\n\t// +optional\n\tmetav1.ListMeta `json:\"metadata,omitempty\"`\n\t// Items is the list of Themes.\n\tItems []Theme `json:\"items\"`\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/webhosting/v1alpha1/types_website.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage v1alpha1\n\nimport (\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n)\n\n// WebsiteSpec defines the desired state of a Website.\ntype WebsiteSpec struct {\n\t// Theme references a Theme object to be used for this Website.\n\tTheme string `json:\"theme\"`\n}\n\n// WebsiteStatus defines the observed state of a Website.\ntype WebsiteStatus struct {\n\t// The generation observed by the Website controller.\n\t// +optional\n\tObservedGeneration int64 `json:\"observedGeneration,omitempty\"`\n\t// Phase is the current phase of this Website.\n\t// +optional\n\tPhase WebsitePhase `json:\"phase,omitempty\"`\n\t// LastTransitionTime is the last time the observedGeneration or phase transitioned from one value to another.\n\t// +optional\n\tLastTransitionTime *metav1.MicroTime `json:\"lastTransitionTime,omitempty\"`\n}\n\n// WebsitePhase describes the phase of a Website.\ntype WebsitePhase string\n\nconst (\n\t// PhasePending means that the Website is not ready yet.\n\tPhasePending WebsitePhase = \"Pending\"\n\t// PhaseReady means that the Website is ready and available.\n\tPhaseReady WebsitePhase = \"Ready\"\n\t// PhaseError means that there is a problem running the Website.\n\tPhaseError WebsitePhase = \"Error\"\n\t// PhaseTerminating means that the Website is shutting down.\n\tPhaseTerminating WebsitePhase = \"Terminating\"\n)\n\n// AllWebsitePhases is a list of all Website phases.\nvar AllWebsitePhases = []WebsitePhase{PhasePending, PhaseReady, PhaseError, PhaseTerminating}\n\n//+kubebuilder:object:root=true\n//+kubebuilder:subresource:status\n//+kubebuilder:printcolumn:name=\"Theme\",type=string,JSONPath=`.spec.theme`\n//+kubebuilder:printcolumn:name=\"Phase\",type=string,JSONPath=`.status.phase`\n//+kubebuilder:printcolumn:name=\"Since\",type=\"date\",JSONPath=\".status.lastTransitionTime\"\n//+kubebuilder:printcolumn:name=\"Age\",type=\"date\",JSONPath=\".metadata.creationTimestamp\"\n\n// Website enables declarative management of hosted websites.\ntype Website struct {\n\tmetav1.TypeMeta `json:\",inline\"`\n\t// Standard object's metadata.\n\t// +optional\n\tmetav1.ObjectMeta `json:\"metadata,omitempty\"`\n\t// Spec contains the specification of the desired behavior of the Website.\n\t// +optional\n\tSpec WebsiteSpec `json:\"spec,omitempty\"`\n\t// Status contains the most recently observed status of the Website.\n\t// +optional\n\tStatus WebsiteStatus `json:\"status,omitempty\"`\n}\n\n//+kubebuilder:object:root=true\n\n// WebsiteList contains a list of Websites.\ntype WebsiteList struct {\n\tmetav1.TypeMeta `json:\",inline\"`\n\t// Standard list metadata.\n\t// +optional\n\tmetav1.ListMeta `json:\"metadata,omitempty\"`\n\t// Items is the list of Websites.\n\tItems []Website `json:\"items\"`\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/apis/webhosting/v1alpha1/zz_generated.deepcopy.go",
    "content": "//go:build !ignore_autogenerated\n\n/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Code generated by controller-gen. DO NOT EDIT.\n\npackage v1alpha1\n\nimport (\n\t\"k8s.io/apimachinery/pkg/runtime\"\n)\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *Theme) DeepCopyInto(out *Theme) {\n\t*out = *in\n\tout.TypeMeta = in.TypeMeta\n\tin.ObjectMeta.DeepCopyInto(&out.ObjectMeta)\n\tout.Spec = in.Spec\n\tout.Status = in.Status\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Theme.\nfunc (in *Theme) DeepCopy() *Theme {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(Theme)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.\nfunc (in *Theme) DeepCopyObject() runtime.Object {\n\tif c := in.DeepCopy(); c != nil {\n\t\treturn c\n\t}\n\treturn nil\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *ThemeList) DeepCopyInto(out *ThemeList) {\n\t*out = *in\n\tout.TypeMeta = in.TypeMeta\n\tin.ListMeta.DeepCopyInto(&out.ListMeta)\n\tif in.Items != nil {\n\t\tin, out := &in.Items, &out.Items\n\t\t*out = make([]Theme, len(*in))\n\t\tfor i := range *in {\n\t\t\t(*in)[i].DeepCopyInto(&(*out)[i])\n\t\t}\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThemeList.\nfunc (in *ThemeList) DeepCopy() *ThemeList {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(ThemeList)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.\nfunc (in *ThemeList) DeepCopyObject() runtime.Object {\n\tif c := in.DeepCopy(); c != nil {\n\t\treturn c\n\t}\n\treturn nil\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *ThemeSpec) DeepCopyInto(out *ThemeSpec) {\n\t*out = *in\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThemeSpec.\nfunc (in *ThemeSpec) DeepCopy() *ThemeSpec {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(ThemeSpec)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *ThemeStatus) DeepCopyInto(out *ThemeStatus) {\n\t*out = *in\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThemeStatus.\nfunc (in *ThemeStatus) DeepCopy() *ThemeStatus {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(ThemeStatus)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *Website) DeepCopyInto(out *Website) {\n\t*out = *in\n\tout.TypeMeta = in.TypeMeta\n\tin.ObjectMeta.DeepCopyInto(&out.ObjectMeta)\n\tout.Spec = in.Spec\n\tin.Status.DeepCopyInto(&out.Status)\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Website.\nfunc (in *Website) DeepCopy() *Website {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(Website)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.\nfunc (in *Website) DeepCopyObject() runtime.Object {\n\tif c := in.DeepCopy(); c != nil {\n\t\treturn c\n\t}\n\treturn nil\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *WebsiteList) DeepCopyInto(out *WebsiteList) {\n\t*out = *in\n\tout.TypeMeta = in.TypeMeta\n\tin.ListMeta.DeepCopyInto(&out.ListMeta)\n\tif in.Items != nil {\n\t\tin, out := &in.Items, &out.Items\n\t\t*out = make([]Website, len(*in))\n\t\tfor i := range *in {\n\t\t\t(*in)[i].DeepCopyInto(&(*out)[i])\n\t\t}\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebsiteList.\nfunc (in *WebsiteList) DeepCopy() *WebsiteList {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(WebsiteList)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.\nfunc (in *WebsiteList) DeepCopyObject() runtime.Object {\n\tif c := in.DeepCopy(); c != nil {\n\t\treturn c\n\t}\n\treturn nil\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *WebsiteSpec) DeepCopyInto(out *WebsiteSpec) {\n\t*out = *in\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebsiteSpec.\nfunc (in *WebsiteSpec) DeepCopy() *WebsiteSpec {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(WebsiteSpec)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *WebsiteStatus) DeepCopyInto(out *WebsiteStatus) {\n\t*out = *in\n\tif in.LastTransitionTime != nil {\n\t\tin, out := &in.LastTransitionTime, &out.LastTransitionTime\n\t\t*out = (*in).DeepCopy()\n\t}\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebsiteStatus.\nfunc (in *WebsiteStatus) DeepCopy() *WebsiteStatus {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(WebsiteStatus)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/controllers/webhosting/suite_test.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage webhosting\n\nimport (\n\t\"path/filepath\"\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\t\"k8s.io/client-go/kubernetes/scheme\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n\t//+kubebuilder:scaffold:imports\n)\n\nvar (\n\tk8sClient client.Client\n\ttestEnv   *envtest.Environment\n)\n\nfunc TestController(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\n\tRunSpecs(t, \"Controller Suite\")\n}\n\nvar _ = BeforeSuite(func() {\n\tlogf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))\n\n\tBy(\"bootstrapping test environment\")\n\ttestEnv = &envtest.Environment{\n\t\tCRDDirectoryPaths:     []string{filepath.Join(\"..\", \"..\", \"config\", \"crd\", \"bases\")},\n\t\tErrorIfCRDPathMissing: true,\n\t}\n\n\tcfg, err := testEnv.Start()\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(cfg).NotTo(BeNil())\n\n\terr = webhostingv1alpha1.AddToScheme(scheme.Scheme)\n\tExpect(err).NotTo(HaveOccurred())\n\n\t//+kubebuilder:scaffold:scheme\n\n\tk8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})\n\tExpect(err).NotTo(HaveOccurred())\n\tExpect(k8sClient).NotTo(BeNil())\n\n})\n\nvar _ = AfterSuite(func() {\n\tBy(\"tearing down the test environment\")\n\terr := testEnv.Stop()\n\tExpect(err).NotTo(HaveOccurred())\n})\n"
  },
  {
    "path": "webhosting-operator/pkg/controllers/webhosting/templates/index.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage templates\n\nimport (\n\t\"embed\"\n\t\"fmt\"\n\t\"html/template\"\n\t\"io\"\n\t\"strings\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n)\n\nvar (\n\t//go:embed index.tmpl\n\tindexTplFS embed.FS\n\t// parsed template\n\tindexTpl *template.Template\n)\n\nfunc init() {\n\tvar err error\n\tindexTpl, err = template.New(\"index.tmpl\").ParseFS(indexTplFS, \"*.tmpl\")\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"error parsing template: %w\", err))\n\t}\n}\n\n// RenderIndexHTML renders the index template and returns it as a string.\nfunc RenderIndexHTML(serverName string, website *webhostingv1alpha1.Website, theme *webhostingv1alpha1.Theme) (string, error) {\n\tout := &strings.Builder{}\n\terr := ExecuteIndexHTMLTemplate(out, serverName, website, theme)\n\treturn out.String(), err\n}\n\n// ExecuteIndexHTMLTemplate renders the index template and writes it to the given io.Writer.\nfunc ExecuteIndexHTMLTemplate(w io.Writer, serverName string, website *webhostingv1alpha1.Website, theme *webhostingv1alpha1.Theme) error {\n\tif err := indexTpl.Execute(w, struct {\n\t\tServerName string\n\t\tWebsite    *webhostingv1alpha1.Website\n\t\tTheme      *webhostingv1alpha1.Theme\n\t}{serverName, website, theme}); err != nil {\n\t\treturn fmt.Errorf(\"error rendering template: %w\", err)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/controllers/webhosting/templates/index.tmpl",
    "content": "<html lang=\"en-US\">\n<head>\n  <title>{{ .Website.Name }}</title>\n  <style>\n      body {\n          background-color: {{ .Theme.Spec.Color }};\n          font-family: {{ .Theme.Spec.FontFamily }}, Arial, sans-serif;\n      }\n\n      .box {\n          background-color: #2D2D2D;\n          margin: 30px auto auto;\n          width: 50%;\n          border: 10px solid cornflowerblue;\n          padding: 20px;\n      }\n\n      h1 {\n          text-align: center;\n          color: coral;\n          font-size: 50px;\n      }\n\n      p {\n          color: white;\n          font-size: 20px;\n          font-family: \"Source Code Pro\", Menlo, Monaco, fixed-width, monospace;\n      }\n\n      a {\n          color: cornflowerblue;\n      }\n  </style>\n</head>\n<body>\n<div class=\"box\">\n  <h1>Welcome to {{ .Website.Name }}</h1>\n  <p>Server name: {{ .ServerName }}</p>\n  <p>This page is hosted on Kubernetes using\n    <a target=\"_blank\"\n       href=\"https://github.com/timebertt/kubernetes-controller-sharding/tree/main/webhosting-operator\">\n      webhosting-operator</a>.\n  </p>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "webhosting-operator/pkg/controllers/webhosting/templates/index_test.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage templates_test\n\nimport (\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/controllers/webhosting/templates\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/controllers/webhosting/templates/internal\"\n)\n\nvar _ = Describe(\"index.html\", func() {\n\tIt(\"should successfully render index page\", func() {\n\t\t// just assert that the template can be rendered properly\n\t\tExpect(RenderIndexHTML(internal.CreateExamples())).To(ContainSubstring(\"Welcome to\"))\n\t})\n})\n"
  },
  {
    "path": "webhosting-operator/pkg/controllers/webhosting/templates/internal/examples.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage internal\n\nimport (\n\t\"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n)\n\n// CreateExamples returns an example set of values for testing purposes.\nfunc CreateExamples() (string, *webhostingv1alpha1.Website, *webhostingv1alpha1.Theme) {\n\treturn \"homepage-381fa2\",\n\t\t&webhostingv1alpha1.Website{\n\t\t\tObjectMeta: v1.ObjectMeta{\n\t\t\t\tName:      \"homepage\",\n\t\t\t\tNamespace: \"project-foo\",\n\t\t\t},\n\t\t\tSpec: webhostingv1alpha1.WebsiteSpec{\n\t\t\t\tTheme: \"fancy\",\n\t\t\t},\n\t\t},\n\t\t&webhostingv1alpha1.Theme{\n\t\t\tObjectMeta: v1.ObjectMeta{\n\t\t\t\tName: \"fancy\",\n\t\t\t},\n\t\t\tSpec: webhostingv1alpha1.ThemeSpec{\n\t\t\t\tColor:      \"darkcyan\",\n\t\t\t\tFontFamily: \"Menlo\",\n\t\t\t},\n\t\t}\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/controllers/webhosting/templates/nginx.conf.tmpl",
    "content": "server {\n    listen       80;\n    listen  [::]:80;\n    server_name  localhost;\n\n    # rewrite /namespace/name to / for requests proxied from Ingress controller\n    # this way, we don't need any Ingress controller specific configuration or objects\n    rewrite ^/{{ .Website.ObjectMeta.Namespace }}/{{ .Website.ObjectMeta.Name }}(.*)$ /$1 last;\n    location / {\n        root   /usr/share/nginx/html;\n        index  index.html;\n    }\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/controllers/webhosting/templates/nginx.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage templates\n\nimport (\n\t\"embed\"\n\t\"fmt\"\n\t\"strings\"\n\t\"text/template\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n)\n\nvar (\n\t//go:embed nginx.conf.tmpl\n\tnginxTplFS embed.FS\n\t// parsed template\n\tnginxTpl *template.Template\n)\n\nfunc init() {\n\tvar err error\n\tnginxTpl, err = template.New(\"nginx.conf.tmpl\").ParseFS(nginxTplFS, \"*.tmpl\")\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"error parsing template: %w\", err))\n\t}\n}\n\n// RenderNginxConf renders the nginx config template and returns it as a string.\nfunc RenderNginxConf(serverName string, website *webhostingv1alpha1.Website) (string, error) {\n\tout := &strings.Builder{}\n\tif err := nginxTpl.Execute(out, struct {\n\t\tServerName string\n\t\tWebsite    *webhostingv1alpha1.Website\n\t}{serverName, website}); err != nil {\n\t\treturn \"\", fmt.Errorf(\"error rendering template: %w\", err)\n\t}\n\treturn out.String(), nil\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/controllers/webhosting/templates/nginx_test.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage templates_test\n\nimport (\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\n\t. \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/controllers/webhosting/templates\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/controllers/webhosting/templates/internal\"\n)\n\nvar _ = Describe(\"nginx.conf\", func() {\n\tconst expectedConfig = `server {\n    listen       80;\n    listen  [::]:80;\n    server_name  localhost;\n\n    # rewrite /namespace/name to / for requests proxied from Ingress controller\n    # this way, we don't need any Ingress controller specific configuration or objects\n    rewrite ^/project-foo/homepage(.*)$ /$1 last;\n    location / {\n        root   /usr/share/nginx/html;\n        index  index.html;\n    }\n}\n`\n\n\tIt(\"should successfully render nginx conf\", func() {\n\t\tserverName, website, _ := internal.CreateExamples()\n\t\tExpect(RenderNginxConf(serverName, website)).To(Equal(expectedConfig))\n\t})\n})\n"
  },
  {
    "path": "webhosting-operator/pkg/controllers/webhosting/templates/templates_suite_test.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage templates_test\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n)\n\nfunc TestTemplates(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"HTML Templates Suite\")\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/controllers/webhosting/templates/testserver/server.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/controllers/webhosting/templates\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/controllers/webhosting/templates/internal\"\n)\n\nfunc main() {\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tserverName, website, theme := internal.CreateExamples()\n\t\tif err := templates.ExecuteIndexHTMLTemplate(w, serverName, website, theme); err != nil {\n\t\t\thttp.Error(w, fmt.Sprintf(\"internal server error: %v\", err), http.StatusInternalServerError)\n\t\t}\n\t})\n\t// nolint:gosec // this is just for testing\n\tif err := http.ListenAndServe(\":9090\", nil); err != nil {\n\t\tpanic(err)\n\t}\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/controllers/webhosting/website_controller.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage webhosting\n\nimport (\n\t\"context\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"maps\"\n\t\"os\"\n\t\"strconv\"\n\n\t\"github.com/go-logr/logr\"\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tnetworkingv1 \"k8s.io/api/networking/v1\"\n\tapiequality \"k8s.io/apimachinery/pkg/api/equality\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/apimachinery/pkg/util/intstr\"\n\t\"k8s.io/apimachinery/pkg/util/json\"\n\t\"k8s.io/client-go/tools/record\"\n\t\"k8s.io/utils/ptr\"\n\t\"sigs.k8s.io/controller-runtime/pkg/builder\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil\"\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\t\"sigs.k8s.io/controller-runtime/pkg/handler\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\tshardcontroller \"github.com/timebertt/kubernetes-controller-sharding/pkg/shard/controller\"\n\tconfigv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/config/v1alpha1\"\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/controllers/webhosting/templates\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/utils\"\n)\n\n// WebsiteReconciler reconciles a Website object.\ntype WebsiteReconciler struct {\n\tClient   client.Client\n\tScheme   *runtime.Scheme\n\tRecorder record.EventRecorder\n\tlogger   logr.Logger\n\n\tConfig *configv1alpha1.WebhostingOperatorConfig\n}\n\n//+kubebuilder:rbac:groups=webhosting.timebertt.dev,resources=websites,verbs=get;list;watch;create;update;patch;delete\n//+kubebuilder:rbac:groups=webhosting.timebertt.dev,resources=websites/status,verbs=get;update;patch\n//+kubebuilder:rbac:groups=webhosting.timebertt.dev,resources=websites/finalizers,verbs=update\n//+kubebuilder:rbac:groups=webhosting.timebertt.dev,resources=themes,verbs=get;list;watch\n//+kubebuilder:rbac:groups=\"\",resources=configmaps,verbs=get;list;watch;create;patch\n//+kubebuilder:rbac:groups=\"\",resources=services,verbs=get;list;watch;create;patch\n//+kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=get;list;watch;create;patch\n//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;patch\n//+kubebuilder:rbac:groups=\"\",resources=events,verbs=create;patch\n\n// RBAC required for sharding\n//+kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,verbs=get;list;watch;update;patch;delete\n\n// Reconcile reconciles a Website object.\nfunc (r *WebsiteReconciler) Reconcile(ctx context.Context, website *webhostingv1alpha1.Website) (reconcile.Result, error) {\n\tlog := logf.FromContext(ctx)\n\tlog.V(1).Info(\"Reconciling website\")\n\n\tbefore := website.DeepCopy()\n\t// always update the status with the latest observed generation\n\twebsite.Status.ObservedGeneration = website.Generation\n\n\treconcileErr := r.reconcileWebsite(ctx, log, website)\n\tif reconcileErr != nil {\n\t\twebsite.Status.Phase = webhostingv1alpha1.PhaseError\n\t}\n\n\t// update the status if needed\n\tif !apiequality.Semantic.DeepEqual(before.Status, website.Status) {\n\t\twebsite.Status.LastTransitionTime = ptr.To(metav1.NowMicro())\n\n\t\tif err := r.Client.Status().Update(ctx, website); err != nil {\n\t\t\t// unable to update status, requeue with backoff\n\t\t\treturn reconcile.Result{}, errors.Join(reconcileErr, fmt.Errorf(\"failed updating Website status: %w\", err))\n\t\t}\n\t}\n\n\treturn reconcile.Result{}, reconcileErr\n}\n\nfunc (r *WebsiteReconciler) reconcileWebsite(ctx context.Context, log logr.Logger, website *webhostingv1alpha1.Website) error {\n\tif website.DeletionTimestamp != nil {\n\t\t// Nothing to do on deletion, all owned objects are cleaned up by the garbage collector.\n\t\t// Set the website's status to terminating and be done with it.\n\t\t// Note: we will only execute this part of the code if the website is deleted with foreground deletion policy,\n\t\t// otherwise it will be gone immediately.\n\t\twebsite.Status.Phase = webhostingv1alpha1.PhaseTerminating\n\n\t\treturn nil\n\t}\n\n\tif website.Spec.Theme == \"\" {\n\t\terr := r.recordError(website, \"ThemeUnspecified\", \"Website doesn't specify a Theme\")\n\n\t\t// Only requeue with backoff if we fail to update the status. We can't do much till the spec changes, so rather wait\n\t\t// for the next update event.\n\t\t// Log the error and forget the object for now.\n\t\tlog.Error(err, \"Unable to reconcile Website\")\n\t\treturn nil\n\t}\n\n\t// retrieve theme\n\ttheme := &webhostingv1alpha1.Theme{}\n\tif err := r.Client.Get(ctx, client.ObjectKey{Name: website.Spec.Theme}, theme); err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\treturn r.recordError(website, \"ThemeNotFound\", \"Theme %s not found\", website.Spec.Theme)\n\t\t}\n\t\treturn r.recordError(website, reasonReconcilerError, \"Error getting Theme %s: %v\", website.Spec.Theme, err)\n\t}\n\n\tserverName := calculateServerName(website)\n\n\t// create downstream objects\n\tconfigMap, err := r.reconcileConfigMap(ctx, log, serverName, website, theme)\n\tif err != nil {\n\t\treturn r.recordError(website, reasonReconcilerError, \"Error reconciling ConfigMap: %v\", err)\n\t}\n\n\tif err := r.reconcileService(ctx, log, serverName, website); err != nil {\n\t\treturn r.recordError(website, reasonReconcilerError, \"Error reconciling Service: %v\", err)\n\t}\n\n\tif err := r.reconcileIngress(ctx, log, serverName, website); err != nil {\n\t\treturn r.recordError(website, reasonReconcilerError, \"Error reconciling Ingress: %v\", err)\n\t}\n\n\tdeployment, err := r.reconcileDeployment(ctx, log, serverName, website, configMap)\n\tif err != nil {\n\t\treturn r.recordError(website, reasonReconcilerError, \"Error reconciling Deployment: %v\", err)\n\t}\n\n\t// update status\n\tnewPhase := webhostingv1alpha1.PhasePending\n\tif utils.IsDeploymentReady(deployment) {\n\t\tnewPhase = webhostingv1alpha1.PhaseReady\n\t}\n\twebsite.Status.Phase = newPhase\n\n\treturn nil\n}\n\nconst reasonReconcilerError = \"ReconcilerError\"\n\nfunc (r *WebsiteReconciler) recordError(website *webhostingv1alpha1.Website, reason, messageFmt string, args ...interface{}) error {\n\tr.Recorder.Eventf(website, corev1.EventTypeWarning, reason, messageFmt, args...)\n\n\t// this error can be returned by the reconciler to retry with backoff\n\treturn fmt.Errorf(messageFmt, args...)\n}\n\nconst (\n\tkeyIndexHTML = \"index.html\"\n\tkeyNginxConf = \"nginx.conf\"\n\tportNameHTTP = \"http\"\n)\n\nfunc (r *WebsiteReconciler) reconcileConfigMap(ctx context.Context, log logr.Logger, serverName string, website *webhostingv1alpha1.Website, theme *webhostingv1alpha1.Theme) (*corev1.ConfigMap, error) {\n\tindexHTML, err := templates.RenderIndexHTML(serverName, website, theme)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnginxConf, err := templates.RenderNginxConf(serverName, website)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tconfigMap := &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{\n\t\tName:      serverName,\n\t\tNamespace: website.Namespace,\n\t}}\n\n\tres, err := controllerutil.CreateOrPatch(ctx, r.Client, configMap, func() error {\n\t\tconfigMap.Labels = mergeMaps(website.Labels, getLabelsForServer(serverName, website.Name))\n\n\t\tconfigMap.Data = map[string]string{\n\t\t\tkeyIndexHTML: indexHTML,\n\t\t\tkeyNginxConf: nginxConf,\n\t\t}\n\n\t\treturn controllerutil.SetControllerReference(website, configMap, r.Scheme)\n\t})\n\tif res != controllerutil.OperationResultNone {\n\t\tlog.V(1).Info(\"Reconciled ConfigMap\", \"result\", res)\n\t}\n\treturn configMap, err\n}\n\nfunc (r *WebsiteReconciler) reconcileService(ctx context.Context, log logr.Logger, serverName string, website *webhostingv1alpha1.Website) error {\n\tservice := &corev1.Service{ObjectMeta: metav1.ObjectMeta{\n\t\tName:      serverName,\n\t\tNamespace: website.Namespace,\n\t}}\n\n\tres, err := controllerutil.CreateOrPatch(ctx, r.Client, service, func() error {\n\t\tservice.Labels = mergeMaps(website.Labels, getLabelsForServer(serverName, website.Name))\n\n\t\tservice.Spec.Type = corev1.ServiceTypeClusterIP\n\t\tservice.Spec.Selector = getLabelsForServer(serverName, website.Name)\n\t\tservice.Spec.Ports = []corev1.ServicePort{{\n\t\t\tName:       portNameHTTP,\n\t\t\tPort:       8080,\n\t\t\tTargetPort: intstr.FromString(portNameHTTP),\n\t\t\tProtocol:   corev1.ProtocolTCP,\n\t\t}}\n\n\t\treturn controllerutil.SetControllerReference(website, service, r.Scheme)\n\t})\n\tif res != controllerutil.OperationResultNone {\n\t\tlog.V(1).Info(\"Reconciled Service\", \"result\", res)\n\t}\n\treturn err\n}\n\nfunc (r *WebsiteReconciler) reconcileIngress(ctx context.Context, log logr.Logger, serverName string, website *webhostingv1alpha1.Website) error {\n\tingress := &networkingv1.Ingress{ObjectMeta: metav1.ObjectMeta{\n\t\tName:      serverName,\n\t\tNamespace: website.Namespace,\n\t}}\n\n\tres, err := controllerutil.CreateOrPatch(ctx, r.Client, ingress, func() error {\n\t\tingress.Labels = mergeMaps(website.Labels, getLabelsForServer(serverName, website.Name))\n\n\t\t// base ingress rule value\n\t\tpathType := networkingv1.PathTypePrefix\n\t\tingressRuleValue := networkingv1.IngressRuleValue{\n\t\t\tHTTP: &networkingv1.HTTPIngressRuleValue{\n\t\t\t\tPaths: []networkingv1.HTTPIngressPath{{\n\t\t\t\t\tPath:     fmt.Sprintf(\"/%s/%s\", website.Namespace, website.Name),\n\t\t\t\t\tPathType: &pathType,\n\t\t\t\t\tBackend: networkingv1.IngressBackend{\n\t\t\t\t\t\tService: &networkingv1.IngressServiceBackend{\n\t\t\t\t\t\t\tName: serverName,\n\t\t\t\t\t\t\tPort: networkingv1.ServiceBackendPort{\n\t\t\t\t\t\t\t\tName: portNameHTTP,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}},\n\t\t\t},\n\t\t}\n\n\t\t// add default rule without hosts\n\t\tingress.Spec.Rules = []networkingv1.IngressRule{{\n\t\t\tIngressRuleValue: ingressRuleValue,\n\t\t}}\n\n\t\tapplyIngressConfigToIngress(r.Config.Ingress, ingress)\n\n\t\tif skipWorkload(website) {\n\t\t\t// don't actually expose website ingresses in load tests\n\t\t\t// use fake ingress class to prevent overloading ingress controller (this is not what we want to load test)\n\t\t\tingress.Spec.IngressClassName = ptr.To(\"fake\")\n\t\t} else if ptr.Deref(ingress.Spec.IngressClassName, \"\") == \"fake\" {\n\t\t\tingress.Spec.IngressClassName = nil\n\t\t}\n\n\t\treturn controllerutil.SetControllerReference(website, ingress, r.Scheme)\n\t})\n\tif res != controllerutil.OperationResultNone {\n\t\tlog.V(1).Info(\"Reconciled Ingress\", \"result\", res)\n\t}\n\treturn err\n}\n\nfunc applyIngressConfigToIngress(config *configv1alpha1.IngressConfiguration, ingress *networkingv1.Ingress) {\n\tif config == nil {\n\t\tconfig = &configv1alpha1.IngressConfiguration{}\n\t}\n\n\t// apply annotations\n\tingress.Annotations = nil\n\tfor key, value := range config.Annotations {\n\t\tmetav1.SetMetaDataAnnotation(&ingress.ObjectMeta, key, value)\n\t}\n\n\t// apply hosts\n\tif len(config.Hosts) > 0 {\n\t\t// use default rule for each host in config\n\t\tingressRuleValue := ingress.Spec.Rules[0].IngressRuleValue\n\n\t\tingress.Spec.Rules = make([]networkingv1.IngressRule, len(config.Hosts))\n\t\tfor i, host := range config.Hosts {\n\t\t\tingress.Spec.Rules[i] = networkingv1.IngressRule{\n\t\t\t\tHost:             host,\n\t\t\t\tIngressRuleValue: ingressRuleValue,\n\t\t\t}\n\t\t}\n\t}\n\n\t// apply TLS config\n\tingress.Spec.TLS = nil\n\tif len(config.TLS) > 0 {\n\t\tingress.Spec.TLS = make([]networkingv1.IngressTLS, len(config.TLS))\n\t\tfor i, tls := range config.TLS {\n\t\t\tingress.Spec.TLS[i] = *tls.DeepCopy()\n\t\t}\n\t}\n}\n\nfunc (r *WebsiteReconciler) reconcileDeployment(ctx context.Context, log logr.Logger, serverName string, website *webhostingv1alpha1.Website, configMap *corev1.ConfigMap) (*appsv1.Deployment, error) {\n\tconfigMapChecksum, err := calculateConfigMapChecksum(configMap)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error calculating checksum of ConfigMap: %w\", err)\n\t}\n\n\tdeployment := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{\n\t\tName:      serverName,\n\t\tNamespace: website.Namespace,\n\t}}\n\n\tres, err := controllerutil.CreateOrPatch(ctx, r.Client, deployment, func() error {\n\t\tdeployment.Labels = mergeMaps(website.Labels, getLabelsForServer(serverName, website.Name))\n\n\t\tdeployment.Spec.Selector = &metav1.LabelSelector{\n\t\t\tMatchLabels: getLabelsForServer(serverName, website.Name),\n\t\t}\n\t\tdeployment.Spec.RevisionHistoryLimit = ptr.To[int32](2)\n\t\tdeployment.Spec.Template.Labels = getLabelsForServer(serverName, website.Name)\n\t\tdeployment.Spec.Template.Annotations = map[string]string{\n\t\t\t\"checksum/configmap\": configMapChecksum,\n\t\t}\n\n\t\tif len(deployment.Spec.Template.Spec.Containers) != 1 {\n\t\t\tdeployment.Spec.Template.Spec.Containers = []corev1.Container{{}}\n\t\t}\n\t\tcontainer := &deployment.Spec.Template.Spec.Containers[0]\n\n\t\tcontainer.Name = \"nginx\"\n\t\tcontainer.Image = \"nginx:1.29-alpine\"\n\t\tcontainer.ImagePullPolicy = corev1.PullIfNotPresent\n\t\tcontainer.Ports = []corev1.ContainerPort{{\n\t\t\tName:          portNameHTTP,\n\t\t\tContainerPort: 80,\n\t\t\tProtocol:      corev1.ProtocolTCP,\n\t\t}}\n\t\tcontainer.VolumeMounts = []corev1.VolumeMount{{\n\t\t\tName:      \"website-data\",\n\t\t\tReadOnly:  true,\n\t\t\tMountPath: \"/usr/share/nginx/html\",\n\t\t}, {\n\t\t\tName:      \"website-config\",\n\t\t\tReadOnly:  true,\n\t\t\tMountPath: \"/etc/nginx/conf.d\",\n\t\t}}\n\n\t\tdeployment.Spec.Template.Spec.Volumes = []corev1.Volume{{\n\t\t\tName: \"website-data\",\n\t\t\tVolumeSource: corev1.VolumeSource{\n\t\t\t\tConfigMap: &corev1.ConfigMapVolumeSource{\n\t\t\t\t\tLocalObjectReference: corev1.LocalObjectReference{Name: configMap.Name},\n\t\t\t\t\tItems: []corev1.KeyToPath{{\n\t\t\t\t\t\tKey:  keyIndexHTML,\n\t\t\t\t\t\tPath: \"index.html\",\n\t\t\t\t\t}},\n\t\t\t\t\tDefaultMode: ptr.To(corev1.ConfigMapVolumeSourceDefaultMode),\n\t\t\t\t},\n\t\t\t},\n\t\t}, {\n\t\t\tName: \"website-config\",\n\t\t\tVolumeSource: corev1.VolumeSource{\n\t\t\t\tConfigMap: &corev1.ConfigMapVolumeSource{\n\t\t\t\t\tLocalObjectReference: corev1.LocalObjectReference{Name: configMap.Name},\n\t\t\t\t\tItems: []corev1.KeyToPath{{\n\t\t\t\t\t\tKey:  keyNginxConf,\n\t\t\t\t\t\tPath: \"nginx.conf\",\n\t\t\t\t\t}},\n\t\t\t\t\tDefaultMode: ptr.To(corev1.ConfigMapVolumeSourceDefaultMode),\n\t\t\t\t},\n\t\t\t},\n\t\t}}\n\n\t\tdeployment.Spec.Replicas = ptr.To[int32](1)\n\t\tif skipWorkload(website) {\n\t\t\t// don't actually run website pods in load tests\n\t\t\t// otherwise, we would need an immense amount of compute power for running dummy websites\n\t\t\tdeployment.Spec.Replicas = ptr.To[int32](0)\n\t\t}\n\n\t\treturn controllerutil.SetControllerReference(website, deployment, r.Scheme)\n\t})\n\tif res != controllerutil.OperationResultNone {\n\t\tlog.V(1).Info(\"Reconciled Deployment\", \"result\", res)\n\t}\n\treturn deployment, err\n}\n\nfunc getLabelsForServer(serverName, name string) map[string]string {\n\treturn map[string]string{\n\t\t\"app\":        \"website\",\n\t\t\"website\":    name,\n\t\t\"server\":     serverName,\n\t\t\"managed-by\": webhostingv1alpha1.WebhostingOperatorName,\n\t}\n}\n\nfunc mergeMaps[M interface{ ~map[K]V }, K comparable, V any](mm ...M) M {\n\tout := M{}\n\tfor _, m := range mm {\n\t\tmaps.Copy(out, m)\n\t}\n\treturn out\n}\n\nfunc calculateServerName(website *webhostingv1alpha1.Website) string {\n\t// Customers might delete the website and create a new one with the same name.\n\t// To avoid clashes in that case, we need to include the website's UID in the name of owned objects.\n\t// Take a sha256 sum and include the first 6 hex characters.\n\tchecksum := sha256.Sum256([]byte(website.UID))\n\treturn website.Name + \"-\" + hex.EncodeToString(checksum[:])[:6]\n}\n\n// calculateConfigMapChecksum calculates a checksum of the given ConfigMap's data. It is supposed to be added to the\n// pod template to trigger rolling updates on ConfigMap changes. This is to force nginx to reload changed config and\n// content.\nfunc calculateConfigMapChecksum(configMap *corev1.ConfigMap) (string, error) {\n\tdataBytes, err := json.Marshal(configMap.Data)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tchecksum := sha256.Sum256(dataBytes)\n\treturn hex.EncodeToString(checksum[:]), nil\n}\n\nconst (\n\tControllerName    = \"website\"\n\twebsiteThemeField = \"spec.theme\"\n)\n\n// SetupWithManager sets up the controller with the Manager.\nfunc (r *WebsiteReconciler) SetupWithManager(mgr manager.Manager, enableSharding bool, controllerRingName, shardName string) error {\n\tif r.Client == nil {\n\t\tr.Client = mgr.GetClient()\n\t}\n\tif r.Scheme == nil {\n\t\tr.Scheme = mgr.GetScheme()\n\t}\n\tif r.Recorder == nil {\n\t\tr.Recorder = mgr.GetEventRecorderFor(ControllerName + \"-controller\")\n\t}\n\n\tif err := mgr.GetCache().IndexField(context.TODO(), &webhostingv1alpha1.Website{}, websiteThemeField, func(obj client.Object) []string {\n\t\treturn []string{obj.(*webhostingv1alpha1.Website).Spec.Theme}\n\t}); err != nil {\n\t\treturn err\n\t}\n\n\tworkers := 15\n\tif override, err := strconv.ParseInt(os.Getenv(\"WEBSITE_CONCURRENT_SYNCS\"), 10, 32); err == nil {\n\t\tworkers = int(override)\n\t}\n\n\tvar (\n\t\t// trigger on spec, status, and annotation changes (manual trigger for testing purposes)\n\t\twebsitePredicate = predicate.Or(\n\t\t\tpredicate.GenerationChangedPredicate{},\n\t\t\tpredicate.AnnotationChangedPredicate{},\n\t\t\tWebsiteStatusChanged,\n\t\t)\n\t\treconciler = reconcile.AsReconciler[*webhostingv1alpha1.Website](r.Client, r)\n\t)\n\n\tif enableSharding {\n\t\t// ACKNOWLEDGE DRAIN OPERATIONS\n\t\t// Use the shardcontroller package as helpers for:\n\t\t// - a predicate that triggers when the drain label is present (even if the actual predicates don't trigger)\n\t\twebsitePredicate = shardcontroller.Predicate(controllerRingName, shardName, websitePredicate)\n\n\t\t// - wrapping the actual reconciler a reconciler that handles the drain operation for us\n\t\treconciler = shardcontroller.NewShardedReconciler(mgr).\n\t\t\tFor(&webhostingv1alpha1.Website{}).\n\t\t\tInControllerRing(controllerRingName).\n\t\t\tWithShardName(shardName).\n\t\t\tMustBuild(reconciler)\n\t}\n\n\tc, err := builder.ControllerManagedBy(mgr).\n\t\tNamed(ControllerName).\n\t\tFor(&webhostingv1alpha1.Website{}, builder.WithPredicates(websitePredicate)).\n\t\t// watch deployments in order to update phase on relevant changes\n\t\t// watch deployments for relevant changes to reconcile them back if changed\n\t\tOwns(&appsv1.Deployment{}, builder.WithPredicates(predicate.Or(\n\t\t\tpredicate.GenerationChangedPredicate{},\n\t\t\tDeploymentAvailabilityChanged,\n\t\t))).\n\t\t// watch owned objects for relevant changes to reconcile them back if changed\n\t\tOwns(&corev1.ConfigMap{}, builder.WithPredicates(ConfigMapDataChanged)).\n\t\tOwns(&corev1.Service{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})).\n\t\tOwns(&networkingv1.Ingress{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})).\n\t\t// watch themes to roll out theme changes to all referencing websites\n\t\tWatches(\n\t\t\t&webhostingv1alpha1.Theme{},\n\t\t\thandler.EnqueueRequestsFromMapFunc(r.MapThemeToWebsites),\n\t\t\tbuilder.WithPredicates(predicate.GenerationChangedPredicate{}),\n\t\t).\n\t\tWithOptions(controller.Options{\n\t\t\tMaxConcurrentReconciles: workers,\n\t\t}).\n\t\tBuild(reconciler)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tr.logger = c.GetLogger()\n\n\treturn nil\n}\n\n// MapThemeToWebsites maps a theme to all websites that use it.\nfunc (r *WebsiteReconciler) MapThemeToWebsites(ctx context.Context, theme client.Object) []reconcile.Request {\n\twebsiteList := &webhostingv1alpha1.WebsiteList{}\n\tif err := r.Client.List(ctx, websiteList, client.MatchingFields{websiteThemeField: theme.GetName()}); err != nil {\n\t\tr.logger.Error(err, \"failed to list websites belonging to theme\", \"theme\", client.ObjectKeyFromObject(theme))\n\t\treturn []reconcile.Request{}\n\t}\n\n\trequests := make([]reconcile.Request, len(websiteList.Items))\n\tfor i, website := range websiteList.Items {\n\t\trequests[i] = reconcile.Request{\n\t\t\tNamespacedName: types.NamespacedName{\n\t\t\t\tName:      website.GetName(),\n\t\t\t\tNamespace: website.GetNamespace(),\n\t\t\t},\n\t\t}\n\t}\n\treturn requests\n}\n\n// WebsiteStatusChanged is a predicate that triggers when the Website status changes.\n// The controller skips updating the status if it didn't change the cached object. In fast consecutive retries, this\n// can lead to a Website in Error state, where the controller doesn't observe its own status update, and skips the\n// transition to Ready afterward because the cached object was still in Ready state.\n// To fix this, we trigger the controller one more time when observing its own status updates to ensure a correct\n// status. This shouldn't hurt the standard case, because the controller doesn't cause any API calls if not needed.\nvar WebsiteStatusChanged = predicate.Funcs{\n\tUpdateFunc: func(e event.UpdateEvent) bool {\n\t\tif e.ObjectOld == nil || e.ObjectNew == nil {\n\t\t\treturn false\n\t\t}\n\n\t\toldWebsite, ok := e.ObjectOld.(*webhostingv1alpha1.Website)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\tnewWebsite, ok := e.ObjectNew.(*webhostingv1alpha1.Website)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\n\t\treturn !apiequality.Semantic.DeepEqual(oldWebsite.Status, newWebsite.Status)\n\t},\n}\n\n// DeploymentAvailabilityChanged is a predicate for filtering relevant Deployment events.\nvar DeploymentAvailabilityChanged = predicate.Funcs{\n\tUpdateFunc: func(e event.UpdateEvent) bool {\n\t\tif e.ObjectOld == nil || e.ObjectNew == nil {\n\t\t\treturn false\n\t\t}\n\n\t\toldDeployment, ok := e.ObjectOld.(*appsv1.Deployment)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\tnewDeployment, ok := e.ObjectNew.(*appsv1.Deployment)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\n\t\treturn utils.IsDeploymentReady(oldDeployment) != utils.IsDeploymentReady(newDeployment)\n\t},\n}\n\n// ConfigMapDataChanged is a predicate for filtering relevant ConfigMap events.\n// Similar to predicate.GenerationChangedPredicate (ConfigMaps don't have a generation).\nvar ConfigMapDataChanged = predicate.Funcs{\n\tUpdateFunc: func(e event.UpdateEvent) bool {\n\t\tif e.ObjectOld == nil || e.ObjectNew == nil {\n\t\t\treturn false\n\t\t}\n\n\t\toldConfigMap, ok := e.ObjectOld.(*corev1.ConfigMap)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\tnewConfigMap, ok := e.ObjectNew.(*corev1.ConfigMap)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\treturn !apiequality.Semantic.DeepEqual(oldConfigMap.Data, newConfigMap.Data)\n\t},\n}\n\n// skipWorkload returns true if the controller should not run any actual workload for this Website, e.g., for load tests\n// or e2e tests.\nfunc skipWorkload(website *webhostingv1alpha1.Website) bool {\n\t_, ok := website.Labels[webhostingv1alpha1.LabelKeySkipWorkload]\n\treturn ok\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/generator/options.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage generator\n\nimport (\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n)\n\ntype GenerateOption interface {\n\tApplyToOptions(options *GenerateOptions)\n}\n\ntype GenerateOptions struct {\n\tLabels         map[string]string\n\tOwnerReference *metav1.OwnerReference\n}\n\nfunc (o *GenerateOptions) ApplyOptions(opts ...GenerateOption) *GenerateOptions {\n\tfor _, opt := range opts {\n\t\topt.ApplyToOptions(o)\n\t}\n\treturn o\n}\n\nfunc (o *GenerateOptions) ApplyToOptions(options *GenerateOptions) {\n\tif len(o.Labels) > 0 {\n\t\tif options.Labels == nil {\n\t\t\toptions.Labels = make(map[string]string, len(o.Labels))\n\t\t}\n\n\t\tfor k, v := range o.Labels {\n\t\t\toptions.Labels[k] = v\n\t\t}\n\t}\n\n\tif ownerRef := o.OwnerReference; ownerRef != nil {\n\t\toptions.OwnerReference = ownerRef.DeepCopy()\n\t}\n}\n\nfunc (o *GenerateOptions) ApplyToObject(obj *metav1.ObjectMeta) {\n\tfor k, v := range o.Labels {\n\t\tmetav1.SetMetaDataLabel(obj, k, v)\n\t}\n\n\tif ownerRef := o.OwnerReference; ownerRef != nil {\n\t\tobj.OwnerReferences = append(obj.OwnerReferences, *ownerRef)\n\t}\n}\n\ntype GenerateOptionFunc func(options *GenerateOptions)\n\nfunc (f GenerateOptionFunc) ApplyToOptions(options *GenerateOptions) {\n\tf(options)\n}\n\nfunc WithLabels(labels map[string]string) GenerateOption {\n\treturn GenerateOptionFunc(func(options *GenerateOptions) {\n\t\tif options.Labels == nil {\n\t\t\toptions.Labels = make(map[string]string, len(labels))\n\t\t}\n\n\t\tfor k, v := range labels {\n\t\t\toptions.Labels[k] = v\n\t\t}\n\t})\n}\n\nfunc WithOwnerReference(ownerRef *metav1.OwnerReference) GenerateOption {\n\treturn GenerateOptionFunc(func(options *GenerateOptions) {\n\t\toptions.OwnerReference = ownerRef.DeepCopy()\n\t})\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/generator/project.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage generator\n\nimport (\n\t\"context\"\n\n\tcorev1 \"k8s.io/api/core/v1\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n)\n\n// CreateProjects creates n random project namespaces.\nfunc CreateProjects(ctx context.Context, c client.Client, n int, opts ...GenerateOption) error {\n\treturn NTimesConcurrently(n, 10, func() error {\n\t\treturn RetryOnError(ctx, 5, func(ctx context.Context) error {\n\t\t\treturn CreateProject(ctx, c, opts...)\n\t\t}, apierrors.IsAlreadyExists)\n\t})\n}\n\n// CreateProject creates a random project namespace.\nfunc CreateProject(ctx context.Context, c client.Client, opts ...GenerateOption) error {\n\toptions := (&GenerateOptions{}).ApplyOptions(opts...)\n\n\tnamespace := &corev1.Namespace{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tGenerateName: \"project-\",\n\t\t\tLabels: map[string]string{\n\t\t\t\twebhostingv1alpha1.LabelKeyProject: webhostingv1alpha1.LabelValueProject,\n\t\t\t},\n\t\t},\n\t}\n\toptions.ApplyToObject(&namespace.ObjectMeta)\n\n\tif err := c.Create(ctx, namespace); err != nil {\n\t\treturn err\n\t}\n\n\tlog.V(1).Info(\"Created project namespace\", \"namespaceName\", namespace.Name)\n\treturn nil\n}\n\n// CleanupProjects deletes all namespaces with the given labels.\nfunc CleanupProjects(ctx context.Context, c client.Client, labels map[string]string) error {\n\tnamespaceList := &corev1.NamespaceList{}\n\tif err := c.List(ctx, namespaceList, client.MatchingLabels(labels)); err != nil {\n\t\treturn err\n\t}\n\n\tfor _, namespace := range namespaceList.Items {\n\t\tif err := c.Delete(ctx, &namespace); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tlog.V(1).Info(\"Cleaned up all project namespaces\")\n\treturn nil\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/generator/reconciler.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage generator\n\nimport (\n\t\"context\"\n\t\"reflect\"\n\t\"time\"\n\n\t\"golang.org/x/time/rate\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/client-go/util/workqueue\"\n\t\"sigs.k8s.io/controller-runtime/pkg/builder\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client/apiutil\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller\"\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\t\"sigs.k8s.io/controller-runtime/pkg/handler\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n)\n\nconst defaultReconcileWorkers = 10\n\n// Every runs the given Func with the specified frequency.\ntype Every struct {\n\tclient.Client\n\n\tName    string\n\tDo      func(ctx context.Context, c client.Client) error\n\tRate    rate.Limit\n\tStop    time.Time\n\tWorkers int\n}\n\nfunc (r *Every) AddToManager(mgr manager.Manager) error {\n\tif r.Client == nil {\n\t\tr.Client = mgr.GetClient()\n\t}\n\n\tinitialDelay := time.Duration(0)\n\tworkers := defaultReconcileWorkers\n\tif r.Workers > 0 {\n\t\tworkers = r.Workers\n\t}\n\n\tvar rateLimiter workqueue.TypedRateLimiter[reconcile.Request] = &workqueue.TypedBucketRateLimiter[reconcile.Request]{\n\t\tLimiter: rate.NewLimiter(r.Rate, int(r.Rate)),\n\t}\n\tif r.Rate < 1 {\n\t\t// Special case for controllers running less frequent than every second:\n\t\t// The token bucket rate limiter would not allow any events as burst is less than 1, so replace it with a custom\n\t\t// rate limiter that always returns a constant delay.\n\t\t// Also, delay the first request when starting the scenario.\n\t\tevery := time.Duration(1 / float64(r.Rate) * float64(time.Second))\n\t\trateLimiter = constantDelayRateLimiter(every)\n\t\tinitialDelay = every\n\t\tworkers = 1\n\t}\n\n\treturn builder.ControllerManagedBy(mgr).\n\t\tNamed(r.Name).\n\t\tWithOptions(controller.Options{\n\t\t\tMaxConcurrentReconciles: workers,\n\t\t\tRateLimiter:             rateLimiter,\n\t\t}).\n\t\tWatchesRawSource(EmitN(workers, initialDelay)).\n\t\tComplete(StopOnContextCanceled(r))\n}\n\nfunc (r *Every) Reconcile(ctx context.Context, _ reconcile.Request) (reconcile.Result, error) {\n\tif !r.Stop.IsZero() && !time.Now().Before(r.Stop) {\n\t\t// stop now\n\t\treturn reconcile.Result{}, nil\n\t}\n\n\treturn reconcile.Result{Requeue: true}, r.Do(ctx, r.Client)\n}\n\n// ForEach runs the given Func for each object of the given kind with the specified frequency.\n// The first execution runs Every after object creation.\ntype ForEach[T client.Object] struct {\n\tclient.Client\n\n\tName    string\n\tDo      func(ctx context.Context, c client.Client, obj T) error\n\tEvery   time.Duration\n\tStop    time.Time\n\tWorkers int\n\n\tgvk schema.GroupVersionKind\n\tobj T\n}\n\nfunc (r *ForEach[T]) AddToManager(mgr manager.Manager) error {\n\tif r.Client == nil {\n\t\tr.Client = mgr.GetClient()\n\t}\n\n\tvar t T\n\tr.obj = reflect.New(reflect.TypeOf(t).Elem()).Interface().(T)\n\n\tvar err error\n\tr.gvk, err = apiutil.GVKForObject(r.obj, mgr.GetScheme())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tworkers := defaultReconcileWorkers\n\tif r.Workers > 0 {\n\t\tworkers = r.Workers\n\t}\n\n\treturn builder.ControllerManagedBy(mgr).\n\t\tNamed(r.Name).\n\t\tWithOptions(controller.Options{\n\t\t\tMaxConcurrentReconciles: workers,\n\t\t\tRateLimiter:             unlimitedRateLimiter(),\n\t\t}).\n\t\tWatches(\n\t\t\tr.obj,\n\t\t\t&handler.Funcs{\n\t\t\t\t// only enqueue create events, after that we reconcile periodically\n\t\t\t\tCreateFunc: func(ctx context.Context, e event.CreateEvent, q workqueue.TypedRateLimitingInterface[reconcile.Request]) {\n\t\t\t\t\tif e.Object == nil {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\t// we should not enqueue directly on creation, but only after Every has passed for the first time\n\t\t\t\t\tq.AddAfter(reconcile.Request{NamespacedName: types.NamespacedName{\n\t\t\t\t\t\tName:      e.Object.GetName(),\n\t\t\t\t\t\tNamespace: e.Object.GetNamespace(),\n\t\t\t\t\t}}, r.Every)\n\t\t\t\t},\n\t\t\t},\n\t\t).\n\t\tComplete(StopOnContextCanceled(r))\n}\n\nfunc (r *ForEach[T]) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {\n\tif !r.Stop.IsZero() && !time.Now().Before(r.Stop) {\n\t\t// stop now\n\t\treturn reconcile.Result{}, nil\n\t}\n\n\tobj := r.obj.DeepCopyObject().(T)\n\tif err := r.Get(ctx, request.NamespacedName, obj); err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\treturn reconcile.Result{}, nil\n\t\t}\n\t\treturn reconcile.Result{}, err\n\t}\n\n\treturn reconcile.Result{RequeueAfter: r.Every}, r.Do(ctx, r.Client, obj)\n}\n\n// unlimitedRateLimiter returns a RateLimiter that doesn't apply any rate limits to the workqueue.\nfunc unlimitedRateLimiter() workqueue.TypedRateLimiter[reconcile.Request] {\n\t// if no limiter is given, MaxOfRateLimiter returns 0 for When and NumRequeues => unlimited\n\treturn &workqueue.TypedMaxOfRateLimiter[reconcile.Request]{}\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/generator/theme.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage generator\n\nimport (\n\t\"context\"\n\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/utils\"\n)\n\nvar (\n\tthemeColors = []string{\"aqua\", \"black\", \"blue\", \"fuchsia\", \"gray\", \"green\", \"lime\", \"maroon\", \"navy\", \"olive\", \"orange\", \"purple\", \"red\", \"silver\", \"teal\", \"white\", \"yellow\"}\n\tthemeFonts  = []string{\"Arial\", \"Verdana\", \"Tahoma\", \"Trebuchet MS\", \"Times New Roman\", \"Georgia\", \"Garamond\", \"Courier New\", \"Brush Script MT\"}\n)\n\n// CreateThemes creates n random themes.\nfunc CreateThemes(ctx context.Context, c client.Client, n int, opts ...GenerateOption) error {\n\treturn NTimesConcurrently(n, 10, func() error {\n\t\treturn RetryOnError(ctx, 5, func(ctx context.Context) error {\n\t\t\treturn CreateTheme(ctx, c, opts...)\n\t\t}, apierrors.IsAlreadyExists)\n\t})\n}\n\n// CreateTheme creates a random theme.\nfunc CreateTheme(ctx context.Context, c client.Client, opts ...GenerateOption) error {\n\toptions := (&GenerateOptions{}).ApplyOptions(opts...)\n\n\ttheme := &webhostingv1alpha1.Theme{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tGenerateName: \"theme-\",\n\t\t},\n\t\tSpec: webhostingv1alpha1.ThemeSpec{\n\t\t\tColor:      utils.PickRandom(themeColors),\n\t\t\tFontFamily: utils.PickRandom(themeFonts),\n\t\t},\n\t}\n\toptions.ApplyToObject(&theme.ObjectMeta)\n\n\tif err := c.Create(ctx, theme); err != nil {\n\t\treturn err\n\t}\n\n\tlog.V(1).Info(\"Created theme\", \"themeName\", theme.Name)\n\treturn nil\n}\n\n// MutateTheme mutates the given theme using the given client and labels.\nfunc MutateTheme(ctx context.Context, c client.Client, theme *webhostingv1alpha1.Theme) error {\n\tpatch := client.MergeFrom(theme.DeepCopy())\n\n\ttheme.Spec.Color = utils.PickRandom(themeColors)\n\ttheme.Spec.FontFamily = utils.PickRandom(themeFonts)\n\n\tif err := c.Patch(ctx, theme, patch); err != nil {\n\t\treturn err\n\t}\n\n\tlog.V(1).Info(\"Mutated theme\", \"themeName\", theme.Name)\n\treturn nil\n}\n\n// MutateRandomTheme mutates a random existing theme using the given client and labels.\nfunc MutateRandomTheme(ctx context.Context, c client.Client, labels map[string]string) error {\n\tthemeList := &webhostingv1alpha1.ThemeList{}\n\tif err := c.List(ctx, themeList, client.MatchingLabels(labels)); err != nil {\n\t\treturn err\n\t}\n\n\tif len(themeList.Items) == 0 {\n\t\tlog.V(1).Info(\"No themes found, skipping mutation\")\n\t\treturn nil\n\t}\n\n\ttheme := utils.PickRandom(themeList.Items)\n\treturn MutateTheme(ctx, c, &theme)\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/generator/utils.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage generator\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/hashicorp/go-multierror\"\n\trbacv1 \"k8s.io/api/rbac/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/apimachinery/pkg/util/wait\"\n\t\"k8s.io/client-go/util/workqueue\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\t\"sigs.k8s.io/controller-runtime/pkg/source\"\n)\n\nvar log = logf.Log\n\n// EmitN returns a source that emits exactly n reconcile requests with the given delay.\n// Use it with the controller builder:\n//\n//\tWatchesRawSource(EmitN(n, time.Second))\n//\n// Or a plain controller:\n//\n//\tWatch(EmitN(n, time.Second))\nfunc EmitN(n int, delay time.Duration) source.Source {\n\treturn source.TypedFunc[reconcile.Request](func(ctx context.Context, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) error {\n\t\tfor i := 0; i < n; i++ {\n\t\t\tqueue.AddAfter(reconcile.Request{NamespacedName: types.NamespacedName{\n\t\t\t\t// use different object names, otherwise queue will merge the requests\n\t\t\t\tName: fmt.Sprintf(\"request-%d\", n),\n\t\t\t}}, delay)\n\t\t}\n\n\t\treturn nil\n\t})\n}\n\n// StopOnContextCanceled wraps the given reconciler so that \"context canceled\" errors are ignored. This is helpful when\n// a reconciler is expected to be canceled (e.g., when the scenario finishes). We neither need to retry nor log on such\n// errors. We can just stop silently.\nfunc StopOnContextCanceled(r reconcile.Reconciler) reconcile.Reconciler {\n\treturn reconcile.Func(func(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {\n\t\tresult, err := r.Reconcile(ctx, request)\n\t\tif errors.Is(err, context.Canceled) {\n\t\t\treturn reconcile.Result{}, nil\n\t\t}\n\t\treturn result, err\n\t})\n}\n\n// NTimesConcurrently runs the given action n times. It distributes the work across the given number of concurrent\n// workers.\nfunc NTimesConcurrently(n, workers int, do func() error) error {\n\tvar (\n\t\twg   sync.WaitGroup\n\t\twork = make(chan struct{}, workers)\n\t\terrs = make(chan error, workers)\n\t)\n\n\t// start workers\n\tfor i := 0; i < workers; i++ {\n\t\twg.Add(1)\n\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\n\t\t\tfor range work {\n\t\t\t\terrs <- do()\n\t\t\t}\n\t\t}()\n\t}\n\n\t// collect all errors\n\tvar (\n\t\tallErrs  *multierror.Error\n\t\terrsDone = make(chan struct{})\n\t)\n\tgo func() {\n\t\tfor err := range errs {\n\t\t\tallErrs = multierror.Append(allErrs, err)\n\t\t}\n\t\tclose(errsDone)\n\t}()\n\n\t// emit n work items\n\tfor i := 0; i < n; i++ {\n\t\twork <- struct{}{}\n\t}\n\tclose(work)\n\n\t// wait for all workers to process all work items\n\twg.Wait()\n\t// signal error worker and wait for it to process all errors\n\tclose(errs)\n\t<-errsDone\n\n\treturn allErrs.ErrorOrNil()\n}\n\n// RetryOnError runs the given action with a short timeout and retries it up to `retries` times if it retruns a\n// retriable error.\n// This is useful when creating a lot of objects in parallel with generateName which can lead to AlreadyExists errors.\nfunc RetryOnError(ctx context.Context, retries int, do func(context.Context) error, retriable func(error) bool) error {\n\ti := 0\n\treturn wait.PollUntilContextTimeout(ctx, 50*time.Millisecond, 10*time.Second, true, func(ctx context.Context) (done bool, err error) {\n\t\terr = do(ctx)\n\t\tif err == nil {\n\t\t\treturn true, nil\n\t\t}\n\n\t\t// stop retrying on non-retriable errors\n\t\tif !retriable(err) {\n\t\t\treturn true, err\n\t\t}\n\n\t\t// stop retrying when reaching the max retry count\n\t\ti++\n\t\tif i > retries {\n\t\t\treturn true, err\n\t\t}\n\n\t\t// otherwise, retry another time\n\t\treturn false, nil\n\t})\n}\n\n// CreateClusterScopedOwnerObject creates a new cluster-scoped object that has a single purpose: being used as an owner\n// for multiple objects that should be cleaned up at once. This is useful for cleaning up a lot of objects (of different\n// kinds) at once with a single DELETE call.\nfunc CreateClusterScopedOwnerObject(ctx context.Context, c client.Client, opts ...GenerateOption) (client.Object, *metav1.OwnerReference, error) {\n\toptions := (&GenerateOptions{}).ApplyOptions(opts...)\n\n\townerObject := &rbacv1.ClusterRole{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tGenerateName: \"experiment-owner-\",\n\t\t},\n\t}\n\toptions.ApplyToObject(&ownerObject.ObjectMeta)\n\n\tif err := c.Create(ctx, ownerObject); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn ownerObject, metav1.NewControllerRef(ownerObject, rbacv1.SchemeGroupVersion.WithKind(\"ClusterRole\")), nil\n}\n\nvar _ workqueue.TypedRateLimiter[reconcile.Request] = constantDelayRateLimiter(0)\n\n// constantDelayRateLimiter delays all requests with a constant duration.\ntype constantDelayRateLimiter time.Duration\n\nfunc (d constantDelayRateLimiter) When(reconcile.Request) time.Duration { return time.Duration(d) }\nfunc (d constantDelayRateLimiter) Forget(reconcile.Request)             {}\nfunc (d constantDelayRateLimiter) NumRequeues(reconcile.Request) int    { return 0 }\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/generator/website.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage generator\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\tcorev1 \"k8s.io/api/core/v1\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/utils\"\n)\n\nvar (\n\twebsiteTracker     WebsiteTracker\n\twebsiteTrackerOnce sync.Once\n)\n\ntype WebsiteTracker interface {\n\tRecordSpecChange(website *webhostingv1alpha1.Website)\n}\n\n// SetWebsiteTracker sets up this package to track website creations and spec updates with the given tracker.\nfunc SetWebsiteTracker(tracker WebsiteTracker) {\n\twebsiteTrackerOnce.Do(func() {\n\t\twebsiteTracker = tracker\n\t})\n}\n\n// CreateWebsites creates n random websites.\nfunc CreateWebsites(ctx context.Context, c client.Client, n int, opts ...GenerateOption) error {\n\treturn NTimesConcurrently(n, 10, func() error {\n\t\treturn RetryOnError(ctx, 5, func(ctx context.Context) error {\n\t\t\treturn CreateWebsite(ctx, c, opts...)\n\t\t}, apierrors.IsAlreadyExists)\n\t})\n}\n\n// CreateWebsite creates a random website.\nfunc CreateWebsite(ctx context.Context, c client.Client, opts ...GenerateOption) error {\n\toptions := (&GenerateOptions{}).ApplyOptions(opts...)\n\n\t// pick random theme and project for a new website\n\tthemeList := &webhostingv1alpha1.ThemeList{}\n\tif err := c.List(ctx, themeList, client.MatchingLabels(options.Labels)); err != nil {\n\t\treturn err\n\t}\n\tif len(themeList.Items) == 0 {\n\t\tlog.V(1).Info(\"No themes found, skipping creation\")\n\t\treturn nil\n\t}\n\n\tnamespaceList := &corev1.NamespaceList{}\n\tif err := c.List(ctx, namespaceList, client.MatchingLabels(options.Labels)); err != nil {\n\t\treturn err\n\t}\n\tif len(namespaceList.Items) == 0 {\n\t\treturn fmt.Errorf(\"no namespaces found, cannot create website\")\n\t}\n\n\twebsite := &webhostingv1alpha1.Website{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      \"experiment-\" + utils.RandomName(8),\n\t\t\tNamespace: utils.PickRandom(namespaceList.Items).Name,\n\t\t},\n\t\tSpec: webhostingv1alpha1.WebsiteSpec{\n\t\t\tTheme: utils.PickRandom(themeList.Items).Name,\n\t\t},\n\t}\n\toptions.ApplyToObject(&website.ObjectMeta)\n\n\tif err := c.Create(ctx, website); err != nil {\n\t\treturn err\n\t}\n\n\tlog.V(1).Info(\"Created website\", \"website\", client.ObjectKeyFromObject(website))\n\tif websiteTracker != nil {\n\t\twebsiteTracker.RecordSpecChange(website)\n\t}\n\n\treturn nil\n}\n\n// MutateWebsite mutates the given website using the given client and labels.\nfunc MutateWebsite(ctx context.Context, c client.Client, website *webhostingv1alpha1.Website, labels map[string]string) error {\n\t// pick new random theme for the website\n\tthemeList := &webhostingv1alpha1.ThemeList{}\n\tif err := c.List(ctx, themeList, client.MatchingLabels(labels)); err != nil {\n\t\treturn err\n\t}\n\tif len(themeList.Items) == 0 {\n\t\tlog.V(1).Info(\"No themes found, skipping mutation\")\n\t\treturn nil\n\t}\n\n\tpatch := client.MergeFrom(website.DeepCopy())\n\n\twebsite.Spec.Theme = utils.PickRandom(themeList.Items).Name\n\n\tif err := c.Patch(ctx, website, patch); err != nil {\n\t\treturn err\n\t}\n\n\tlog.V(1).Info(\"Mutated website\", \"website\", client.ObjectKeyFromObject(website))\n\tif websiteTracker != nil {\n\t\twebsiteTracker.RecordSpecChange(website)\n\t}\n\n\treturn nil\n}\n\n// ReconcileWebsite triggers reconciliation of the given website by updating an annotation.\nfunc ReconcileWebsite(ctx context.Context, c client.Client, website *webhostingv1alpha1.Website) error {\n\tpatch := client.MergeFrom(website.DeepCopy())\n\tmetav1.SetMetaDataAnnotation(&website.ObjectMeta, \"experiment-reconcile\", time.Now().UTC().Format(time.RFC3339))\n\n\tif err := c.Patch(ctx, website, patch); err != nil {\n\t\treturn err\n\t}\n\n\tlog.V(1).Info(\"Triggered reconciliation of website\", \"website\", client.ObjectKeyFromObject(website))\n\treturn nil\n}\n\n// DeleteWebsite deletes a random existing website using the given client and labels.\nfunc DeleteWebsite(ctx context.Context, c client.Client, labels map[string]string) error {\n\twebsiteList := &webhostingv1alpha1.WebsiteList{}\n\tif err := c.List(ctx, websiteList, client.MatchingLabels(labels)); err != nil {\n\t\treturn err\n\t}\n\n\tif len(websiteList.Items) == 0 {\n\t\tlog.V(1).Info(\"No websites found, skipping deletion\")\n\t\treturn nil\n\t}\n\n\twebsite := utils.PickRandom(websiteList.Items)\n\tif err := c.Delete(ctx, &website); err != nil {\n\t\treturn err\n\t}\n\n\tlog.V(1).Info(\"Deleted website\", \"website\", client.ObjectKeyFromObject(&website))\n\treturn nil\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/scenario/all/all.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package all imports all scenarios.\npackage all\n\nimport (\n\t_ \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/scenario/basic\"\n\t_ \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/scenario/chaos\"\n\t_ \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/scenario/rolling-update\"\n\t_ \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/scenario/scale-out\"\n)\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/scenario/base/base.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage base\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/util/uuid\"\n\t\"k8s.io/apimachinery/pkg/util/wait\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/generator\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/tracker\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/utils\"\n)\n\n// Scenario provides a common base implemenation for parts of the experiment.Scenario interface.\ntype Scenario struct {\n\t// Delegate is responsible for performing the actual experiment actions.\n\tDelegate Delegate\n\n\tScenarioName string\n\n\tLog     logr.Logger\n\tManager manager.Manager\n\tClient  client.Client\n\tdone    chan struct{}\n\n\tRunID    string\n\tLabels   map[string]string\n\tOwnerRef *metav1.OwnerReference\n}\n\n// Delegate combines the actual experiment actions in a single interface.\ntype Delegate interface {\n\tPrepare(ctx context.Context) error\n\tRun(ctx context.Context) error\n}\n\nfunc (s *Scenario) Name() string {\n\treturn s.ScenarioName\n}\n\nfunc (s *Scenario) Done() <-chan struct{} {\n\treturn s.done\n}\n\nfunc (s *Scenario) AddToManager(mgr manager.Manager) error {\n\ts.Log = logf.Log.WithName(\"scenario\").WithName(s.ScenarioName)\n\ts.Manager = mgr\n\ts.Client = mgr.GetClient()\n\ts.done = make(chan struct{})\n\n\ts.Labels = map[string]string{\n\t\t\"generated-by\": \"experiment\",\n\t\t\"scenario\":     s.ScenarioName,\n\n\t\twebhostingv1alpha1.LabelKeySkipWorkload: \"true\",\n\t}\n\n\treturn mgr.Add(s)\n}\n\nfunc (s *Scenario) Start(ctx context.Context) (err error) {\n\tdefer close(s.done)\n\ts.Log.Info(\"Scenario started\")\n\n\tcleanup, err := s.prepare(ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer func() {\n\t\ts.Log.Info(\"Cleaning up\")\n\t\tcleanupCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n\t\tdefer cancel()\n\n\t\tif cleanupErr := cleanup(cleanupCtx); cleanupErr != nil {\n\t\t\t// if another error occurred during execution, it has priority\n\t\t\t// otherwise, return the cleanup error\n\t\t\tif err != nil {\n\t\t\t\ts.Log.Error(cleanupErr, \"Failed cleaning up\")\n\t\t\t} else {\n\t\t\t\terr = cleanupErr\n\t\t\t}\n\n\t\t\treturn\n\t\t}\n\n\t\ts.Log.Info(\"Cleanup done\")\n\t}()\n\n\tif err := s.Delegate.Prepare(ctx); err != nil {\n\t\treturn err\n\t}\n\n\ts.Log.Info(\"Scenario prepared\")\n\n\t// give monitoring stack some time to observe objects\n\tselect {\n\tcase <-ctx.Done():\n\t\ts.Log.Info(\"Scenario canceled\")\n\t\treturn ctx.Err()\n\tcase <-time.After(30 * time.Second):\n\t}\n\n\twebsiteTracker := &tracker.WebsiteTracker{}\n\tif err := websiteTracker.AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding website-tracker: %w\", err)\n\t}\n\tgenerator.SetWebsiteTracker(websiteTracker)\n\n\ts.Log.Info(\"Scenario running\")\n\n\tif err := s.Delegate.Run(ctx); err != nil {\n\t\treturn err\n\t}\n\n\ts.Log.Info(\"Scenario finished\")\n\treturn nil\n}\n\nfunc (s *Scenario) prepare(ctx context.Context) (func(context.Context) error, error) {\n\t// determine run ID\n\t// env var can be specified in the pod spec, e.g. from the pod's uid so that experiment's own metrics can be selected\n\t// by run ID\n\ts.RunID = os.Getenv(\"RUN_ID\")\n\tif s.RunID == \"\" {\n\t\ts.RunID = string(uuid.NewUUID())\n\t}\n\n\t// use unique label set per scenario run\n\ts.Labels[\"run-id\"] = s.RunID\n\ts.Log = s.Log.WithValues(\"run-id\", s.RunID)\n\n\ts.Log.Info(\"Creating owner object\")\n\townerObject, ownerRef, err := generator.CreateClusterScopedOwnerObject(ctx, s.Client, generator.WithLabels(s.Labels))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ts.OwnerRef = ownerRef\n\ts.Log.Info(\"Created owner object\", \"object\", ownerObject)\n\n\tcleanup := func(cleanupCtx context.Context) error {\n\t\tif err := s.Client.Delete(cleanupCtx, ownerObject, client.PropagationPolicy(metav1.DeletePropagationForeground)); err != nil {\n\t\t\treturn fmt.Errorf(\"failed cleaning up owner object %T %s\", ownerObject, client.ObjectKeyFromObject(ownerObject))\n\t\t}\n\t\treturn nil\n\t}\n\n\t// Label all observed components with the experiment's run ID to trigger a rollout (start from a fresh state).\n\t// The run ID is added to all scraped metrics in the ServiceMonitor.\n\t// This allows calculating rates of individual runs without considering metrics of adjacent runs.\n\ts.Log.Info(\"Restarting/labeling observed components\")\n\tobservedComponents := []struct{ namespace, name string }{\n\t\t{shardingv1alpha1.NamespaceSystem, \"sharder\"},\n\t\t{webhostingv1alpha1.NamespaceSystem, webhostingv1alpha1.WebhostingOperatorName},\n\t}\n\n\tfor _, c := range observedComponents {\n\t\tif err := s.injectRunIDLabel(ctx, c.namespace, c.name); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// wait for all observed components to be rolled out and ready again\n\tfor _, c := range observedComponents {\n\t\tif err := s.waitForDeployment(ctx, c.namespace, c.name); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed waiting for deployment: %w\", err)\n\t\t}\n\t}\n\n\t// clean up orphaned leases after instances have been terminated\n\t// this only speeds up the cleaning and allows us to start sooner, but is not required otherwise\n\tif err := s.Client.DeleteAllOf(ctx, &coordinationv1.Lease{},\n\t\tclient.InNamespace(webhostingv1alpha1.NamespaceSystem), client.MatchingLabels{\"alpha.sharding.timebertt.dev/state\": \"dead\"},\n\t); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// wait for all shard leases to be ready\n\tif err := s.waitForShardLeases(ctx); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed waiting for shard leases: %w\", err)\n\t}\n\n\treturn cleanup, nil\n}\n\nfunc (s *Scenario) injectRunIDLabel(ctx context.Context, namespace, name string) error {\n\tdeployment := &appsv1.Deployment{}\n\tif err := s.Client.Get(ctx, client.ObjectKey{Namespace: namespace, Name: name}, deployment); err != nil {\n\t\treturn err\n\t}\n\n\tpatch := client.MergeFrom(deployment.DeepCopy())\n\tmetav1.SetMetaDataLabel(&deployment.Spec.Template.ObjectMeta, \"label.prometheus.io/run_id\", s.RunID)\n\treturn s.Client.Patch(ctx, deployment, patch)\n}\n\nfunc (s *Scenario) waitForDeployment(ctx context.Context, namespace, name string) error {\n\tvar lastError error\n\tif err := wait.PollUntilContextTimeout(ctx, 2*time.Second, 2*time.Minute, false, func(ctx context.Context) (done bool, err error) {\n\t\tdeployment := &appsv1.Deployment{}\n\t\tif err := s.Client.Get(ctx, client.ObjectKey{Namespace: namespace, Name: name}, deployment); err != nil {\n\t\t\treturn true, err\n\t\t}\n\n\t\tif !utils.IsDeploymentReady(deployment) {\n\t\t\tlastError = fmt.Errorf(\"deployment %s is not available\", client.ObjectKeyFromObject(deployment))\n\t\t\treturn false, nil\n\t\t}\n\n\t\treturn true, nil\n\t}); err != nil {\n\t\tif errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {\n\t\t\treturn lastError\n\t\t}\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (s *Scenario) waitForShardLeases(ctx context.Context) error {\n\tvar lastError error\n\tif err := wait.PollUntilContextTimeout(ctx, 2*time.Second, 2*time.Minute, false, func(ctx context.Context) (done bool, err error) {\n\t\tleaseList := &coordinationv1.LeaseList{}\n\t\tif err := s.Client.List(ctx, leaseList,\n\t\t\tclient.InNamespace(webhostingv1alpha1.NamespaceSystem), client.MatchingLabels{shardingv1alpha1.LabelControllerRing: webhostingv1alpha1.WebhostingOperatorName},\n\t\t); err != nil {\n\t\t\treturn true, err\n\t\t}\n\n\t\tfor _, lease := range leaseList.Items {\n\t\t\tstate := lease.Labels[\"alpha.sharding.timebertt.dev/state\"]\n\t\t\tif state != \"ready\" {\n\t\t\t\tlastError = fmt.Errorf(\"shard lease %s is in state %q\", client.ObjectKeyFromObject(&lease), state)\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t}\n\n\t\treturn true, nil\n\t}); err != nil {\n\t\tif errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {\n\t\t\treturn lastError\n\t\t}\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// Wait does blocks until the given duration has passed or returns an error when the context is canceled.\nfunc (s *Scenario) Wait(ctx context.Context, d time.Duration) error {\n\tselect {\n\tcase <-ctx.Done():\n\t\ts.Log.Info(\"Scenario canceled\")\n\t\treturn ctx.Err()\n\tcase <-time.After(d):\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/scenario/basic/basic.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage basic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"golang.org/x/time/rate\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/generator\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/scenario/base\"\n)\n\nconst ScenarioName = \"basic\"\n\nfunc init() {\n\ts := &scenario{}\n\ts.Scenario = &base.Scenario{\n\t\tScenarioName: ScenarioName,\n\t\tDelegate:     s,\n\t}\n\n\texperiment.RegisterScenario(s)\n}\n\ntype scenario struct {\n\t*base.Scenario\n}\n\nfunc (s *scenario) Description() string {\n\treturn \"Basic load test, create 9k websites in 15 minutes\"\n}\n\nfunc (s *scenario) LongDescription() string {\n\treturn `The ` + ScenarioName + ` scenario combines several operations typical for a lively operator environment:\n- website creation: 10800 over 15m\n- website deletion: 1800 over 15m\n- website spec changes: 1/m per object, max 150/s\n`\n}\n\nfunc (s *scenario) Prepare(ctx context.Context) error {\n\ts.Log.Info(\"Preparing themes\")\n\tif err := generator.CreateThemes(ctx, s.Client, 50, generator.WithLabels(s.Labels), generator.WithOwnerReference(s.OwnerRef)); err != nil {\n\t\treturn err\n\t}\n\n\ts.Log.Info(\"Preparing projects\")\n\tif err := generator.CreateProjects(ctx, s.Client, 20, generator.WithLabels(s.Labels), generator.WithOwnerReference(s.OwnerRef)); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (s *scenario) Run(ctx context.Context) error {\n\t// website-generator: creates about 10800 websites over  15 minutes\n\t// website-deleter:   deletes about  1800 websites over  15 minutes\n\t// => in total, there will be about  9000 websites after 15 minutes\n\tif err := (&generator.Every{\n\t\tName: \"website-generator\",\n\t\tDo: func(ctx context.Context, c client.Client) error {\n\t\t\treturn generator.CreateWebsite(ctx, c, generator.WithLabels(s.Labels))\n\t\t},\n\t\tRate: rate.Limit(12),\n\t}).AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding website-generator: %w\", err)\n\t}\n\n\tif err := (&generator.Every{\n\t\tName: \"website-deleter\",\n\t\tDo: func(ctx context.Context, c client.Client) error {\n\t\t\treturn generator.DeleteWebsite(ctx, c, s.Labels)\n\t\t},\n\t\tRate: rate.Limit(2),\n\t}).AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding website-deleter: %w\", err)\n\t}\n\n\t// trigger individual spec changes for website once per minute\n\t// => peaks at about 150 spec changes per second at the end of the experiment\n\t// (triggers roughly double the reconciliation rate in website controller because of deployment watches)\n\tif err := (&generator.ForEach[*webhostingv1alpha1.Website]{\n\t\tName: \"website-mutator\",\n\t\tDo: func(ctx context.Context, c client.Client, obj *webhostingv1alpha1.Website) error {\n\t\t\treturn client.IgnoreNotFound(generator.MutateWebsite(ctx, c, obj, s.Labels))\n\t\t},\n\t\tEvery: time.Minute,\n\t}).AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding website-mutator: %w\", err)\n\t}\n\n\treturn s.Wait(ctx, 15*time.Minute)\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/scenario/chaos/chaos.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage chaos\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"golang.org/x/time/rate\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/generator\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/scenario/base\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/utils\"\n)\n\nconst ScenarioName = \"chaos\"\n\nfunc init() {\n\ts := &scenario{}\n\ts.Scenario = &base.Scenario{\n\t\tScenarioName: ScenarioName,\n\t\tDelegate:     s,\n\t}\n\n\texperiment.RegisterScenario(s)\n}\n\ntype scenario struct {\n\t*base.Scenario\n}\n\nfunc (s *scenario) Description() string {\n\treturn \"Create 4.5k websites over 15 minutes and terminate a random shard every 5 minutes\"\n}\n\nfunc (s *scenario) LongDescription() string {\n\treturn `The ` + ScenarioName + ` scenario generates load and chaos for the webhosting-operator:\n- website creation: 4500 over 15m\n- website spec changes: 0.5/m per object, max 37.5/s\n- shard termination (pod deletion): 1/m\n`\n}\n\nfunc (s *scenario) Prepare(ctx context.Context) error {\n\ts.Log.Info(\"Preparing themes\")\n\tif err := generator.CreateThemes(ctx, s.Client, 50, generator.WithLabels(s.Labels), generator.WithOwnerReference(s.OwnerRef)); err != nil {\n\t\treturn err\n\t}\n\n\ts.Log.Info(\"Preparing projects\")\n\tif err := generator.CreateProjects(ctx, s.Client, 20, generator.WithLabels(s.Labels), generator.WithOwnerReference(s.OwnerRef)); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (s *scenario) Run(ctx context.Context) error {\n\t// website-generator: creates about 4500 websites over 15 minutes\n\tif err := (&generator.Every{\n\t\tName: \"website-generator\",\n\t\tDo: func(ctx context.Context, c client.Client) error {\n\t\t\treturn generator.CreateWebsite(ctx, c, generator.WithLabels(s.Labels))\n\t\t},\n\t\tRate: rate.Limit(5),\n\t}).AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding website-generator: %w\", err)\n\t}\n\n\t// trigger individual spec changes for website every other minute\n\t// => peaks at about 37.5 spec changes per second at the end of the experiment\n\t// (triggers roughly double the reconciliation rate in website controller because of deployment watches)\n\tif err := (&generator.ForEach[*webhostingv1alpha1.Website]{\n\t\tName: \"website-mutator\",\n\t\tDo: func(ctx context.Context, c client.Client, obj *webhostingv1alpha1.Website) error {\n\t\t\treturn client.IgnoreNotFound(generator.MutateWebsite(ctx, c, obj, s.Labels))\n\t\t},\n\t\tEvery: 2 * time.Minute,\n\t}).AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding website-mutator: %w\", err)\n\t}\n\n\t// Terminate a random shard every 5 minutes\n\tif err := (&generator.Every{\n\t\tName: \"shard-terminator\",\n\t\tDo:   terminateRandomShard,\n\t\tRate: rate.Every(5 * time.Minute),\n\t}).AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding shard-terminator: %w\", err)\n\t}\n\n\treturn s.Wait(ctx, 15*time.Minute)\n}\n\nfunc terminateRandomShard(ctx context.Context, c client.Client) error {\n\tlog := logf.FromContext(ctx)\n\n\tpodList := &corev1.PodList{}\n\tif err := c.List(ctx, podList,\n\t\tclient.InNamespace(webhostingv1alpha1.NamespaceSystem),\n\t\tclient.MatchingLabels{\"app.kubernetes.io/name\": webhostingv1alpha1.WebhostingOperatorName},\n\t); err != nil {\n\t\treturn err\n\t}\n\n\tif len(podList.Items) == 0 {\n\t\tlog.Info(\"No shards found, skipping termination\")\n\t\treturn nil\n\t}\n\n\tpod := utils.PickRandom(podList.Items)\n\tif err := c.Delete(ctx, &pod); err != nil {\n\t\treturn err\n\t}\n\n\tlog.Info(\"Terminated shard\", \"pod\", client.ObjectKeyFromObject(&pod))\n\treturn nil\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/scenario/rolling-update/rolling_update.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage rolling_update\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"golang.org/x/time/rate\"\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/generator\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/scenario/base\"\n)\n\nconst ScenarioName = \"rolling-update\"\n\nfunc init() {\n\ts := &scenario{}\n\ts.Scenario = &base.Scenario{\n\t\tScenarioName: ScenarioName,\n\t\tDelegate:     s,\n\t}\n\n\texperiment.RegisterScenario(s)\n}\n\ntype scenario struct {\n\t*base.Scenario\n}\n\nfunc (s *scenario) Description() string {\n\treturn \"Create 9k websites in 15 minutes while rolling the operator\"\n}\n\nfunc (s *scenario) LongDescription() string {\n\treturn `The ` + ScenarioName + ` scenario combines several operations typical for a lively operator environment with rolling updates:\n- website creation: 10800 over 15m\n- website deletion: 1800 over 15m\n- website spec changes: 1/m per object, max 150/s\n- rolling update of webhosting-operator: 1 every 5m\n`\n}\n\nfunc (s *scenario) Prepare(ctx context.Context) error {\n\ts.Log.Info(\"Preparing themes\")\n\tif err := generator.CreateThemes(ctx, s.Client, 50, generator.WithLabels(s.Labels), generator.WithOwnerReference(s.OwnerRef)); err != nil {\n\t\treturn err\n\t}\n\n\ts.Log.Info(\"Preparing projects\")\n\tif err := generator.CreateProjects(ctx, s.Client, 20, generator.WithLabels(s.Labels), generator.WithOwnerReference(s.OwnerRef)); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (s *scenario) Run(ctx context.Context) error {\n\t// website-generator: creates about 10800 websites over  15 minutes\n\t// website-deleter:   deletes about  1800 websites over  15 minutes\n\t// => in total, there will be about  9000 websites after 15 minutes\n\tif err := (&generator.Every{\n\t\tName: \"website-generator\",\n\t\tDo: func(ctx context.Context, c client.Client) error {\n\t\t\treturn generator.CreateWebsite(ctx, c, generator.WithLabels(s.Labels))\n\t\t},\n\t\tRate: rate.Limit(12),\n\t}).AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding website-generator: %w\", err)\n\t}\n\n\tif err := (&generator.Every{\n\t\tName: \"website-deleter\",\n\t\tDo: func(ctx context.Context, c client.Client) error {\n\t\t\treturn generator.DeleteWebsite(ctx, c, s.Labels)\n\t\t},\n\t\tRate: rate.Limit(2),\n\t}).AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding website-deleter: %w\", err)\n\t}\n\n\t// trigger individual spec changes for website once per minute\n\t// => peaks at about 150 spec changes per second at the end of the experiment\n\t// (triggers roughly double the reconciliation rate in website controller because of deployment watches)\n\tif err := (&generator.ForEach[*webhostingv1alpha1.Website]{\n\t\tName: \"website-mutator\",\n\t\tDo: func(ctx context.Context, c client.Client, obj *webhostingv1alpha1.Website) error {\n\t\t\treturn client.IgnoreNotFound(generator.MutateWebsite(ctx, c, obj, s.Labels))\n\t\t},\n\t\tEvery: time.Minute,\n\t}).AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding website-mutator: %w\", err)\n\t}\n\n\t// trigger a rolling update of the webhosting-operator every 5 minutes\n\tif err := (&generator.Every{\n\t\tName: \"rolling-updater\",\n\t\tDo:   triggerRollingUpdate,\n\t\tRate: rate.Every(5 * time.Minute),\n\t}).AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding rolling-updater: %w\", err)\n\t}\n\n\treturn s.Wait(ctx, 15*time.Minute)\n}\n\nfunc triggerRollingUpdate(ctx context.Context, c client.Client) error {\n\tkey := client.ObjectKey{Namespace: webhostingv1alpha1.NamespaceSystem, Name: webhostingv1alpha1.WebhostingOperatorName}\n\n\tvar object client.Object = &appsv1.Deployment{}\n\tif err := c.Get(ctx, key, object); err != nil {\n\t\tif !apierrors.IsNotFound(err) {\n\t\t\treturn err\n\t\t}\n\n\t\tobject = &appsv1.StatefulSet{}\n\t\tif err := c.Get(ctx, key, object); err != nil {\n\t\t\tif !apierrors.IsNotFound(err) {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tpanic(\"neither Deployment nor StatefulSet found for webhosting-operator, aborting experiment\")\n\t\t}\n\t}\n\n\tpatch := client.RawPatch(types.MergePatchType, []byte(`{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"rolling-update\":\"`+time.Now().UTC().Format(time.RFC3339)+`\"}}}}}`))\n\tif err := c.Patch(ctx, object, patch); err != nil {\n\t\treturn err\n\t}\n\n\tlogf.FromContext(ctx).Info(\"Triggered rolling update\")\n\treturn nil\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/scenario/scale-out/scale_out.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage scaleout\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"golang.org/x/time/rate\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/generator\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/experiment/scenario/base\"\n)\n\nconst ScenarioName = \"scale-out\"\n\nfunc init() {\n\ts := &scenario{}\n\ts.Scenario = &base.Scenario{\n\t\tScenarioName: ScenarioName,\n\t\tDelegate:     s,\n\t}\n\n\texperiment.RegisterScenario(s)\n}\n\ntype scenario struct {\n\t*base.Scenario\n}\n\nfunc (s *scenario) Description() string {\n\treturn \"Measure scale-out properties with a high churn rate\"\n}\n\nfunc (s *scenario) LongDescription() string {\n\treturn `The ` + ScenarioName + ` scenario is designed to overload 5 webhosting-operator instances with 5 workers within 15m:\n- website creation: 9000 over 15m\n- website spec changes: 2/m per object, max 300/s\n`\n}\n\nfunc (s *scenario) Prepare(ctx context.Context) error {\n\ts.Log.Info(\"Preparing themes\")\n\tif err := generator.CreateThemes(ctx, s.Client, 50, generator.WithLabels(s.Labels), generator.WithOwnerReference(s.OwnerRef)); err != nil {\n\t\treturn err\n\t}\n\n\ts.Log.Info(\"Preparing projects\")\n\tif err := generator.CreateProjects(ctx, s.Client, 20, generator.WithLabels(s.Labels), generator.WithOwnerReference(s.OwnerRef)); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (s *scenario) Run(ctx context.Context) error {\n\t// website-generator: creates about 9000 websites over 15 minutes\n\tif err := (&generator.Every{\n\t\tName: \"website-generator\",\n\t\tDo: func(ctx context.Context, c client.Client) error {\n\t\t\treturn generator.CreateWebsite(ctx, c, generator.WithLabels(s.Labels))\n\t\t},\n\t\tRate: rate.Limit(10),\n\t}).AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding website-generator: %w\", err)\n\t}\n\n\t// trigger individual spec changes for website twice per minute\n\t// => peaks at about 300 spec changes per second at the end of the experiment\n\t// (triggers roughly double the reconciliation rate in website controller because of deployment watches)\n\tif err := (&generator.ForEach[*webhostingv1alpha1.Website]{\n\t\tName: \"website-mutator\",\n\t\tDo: func(ctx context.Context, c client.Client, obj *webhostingv1alpha1.Website) error {\n\t\t\treturn client.IgnoreNotFound(generator.MutateWebsite(ctx, c, obj, s.Labels))\n\t\t},\n\t\tEvery:   30 * time.Second,\n\t\tWorkers: 20,\n\t}).AddToManager(s.Manager); err != nil {\n\t\treturn fmt.Errorf(\"error adding website-mutator: %w\", err)\n\t}\n\n\treturn s.Wait(ctx, 15*time.Minute)\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/scenario.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage experiment\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n)\n\nvar registry = make(map[string]Scenario)\n\n// Scenario is an evaluation scenario that can be executed by experiment.\ntype Scenario interface {\n\t// Name returns the name of the scenario.\n\tName() string\n\t// Description returns the description of the scenario.\n\tDescription() string\n\t// LongDescription returns the description of the scenario.\n\tLongDescription() string\n\t// Done is closed once the scenario is finished.\n\tDone() <-chan struct{}\n\t// AddToManager adds all runnables of the scenario to the manager.\n\tAddToManager(manager.Manager) error\n}\n\n// RegisterScenario registers a new scenario in the registry.\nfunc RegisterScenario(s Scenario) {\n\tif _, ok := registry[s.Name()]; ok {\n\t\tpanic(fmt.Errorf(\"scenario %q already registered\", s.Name()))\n\t}\n\n\tregistry[s.Name()] = s\n}\n\n// GetAllScenarios returns all registered scenarios.\nfunc GetAllScenarios() []Scenario {\n\tall := make([]Scenario, 0, len(registry))\n\tfor _, s := range registry {\n\t\tall = append(all, s)\n\t}\n\n\tsort.Slice(all, func(i, j int) bool {\n\t\treturn all[i].Name() < all[j].Name()\n\t})\n\n\treturn all\n}\n\n// GetScenario gets a single registered scenario by name.\nfunc GetScenario(s string) Scenario {\n\treturn registry[s]\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/tracker/tracker.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage tracker\n\nimport (\n\t\"cmp\"\n\t\"slices\"\n\t\"sync\"\n)\n\n// tracker is a generic map that only allows manipulating keys via the set operation (\"create or update\").\n// It synchronizes access to the map itself, but not to the contained values. Values need to synchronize concurrent\n// access on their own.\n// This is done to efficiently store multi-level tracking information in a concurrency safe way.\ntype tracker[K cmp.Ordered, V any] struct {\n\tlock   sync.RWMutex\n\tvalues map[K]*V\n\tnew    func() *V\n}\n\n// sortedValues returns a slice of values in the tracker's map sorted by their respective keys.\nfunc (t *tracker[K, V]) sortedValues() []*V {\n\tt.lock.RLock()\n\tdefer t.lock.RUnlock()\n\n\tkeys := make([]K, 0, len(t.values))\n\tfor k := range t.values {\n\t\tkeys = append(keys, k)\n\t}\n\tslices.Sort(keys)\n\n\tvalues := make([]*V, 0, len(t.values))\n\tfor _, k := range keys {\n\t\tvalues = append(values, t.values[k])\n\t}\n\n\treturn values\n}\n\n// set adds a new key to the map and runs mutate on its value, or mutates the value of an existing key.\nfunc (t *tracker[K, V]) set(key K, mutate func(v *V)) {\n\t// fast path for existing keys\n\tt.lock.RLock()\n\tif v, ok := t.values[key]; ok {\n\t\tdefer t.lock.RUnlock()\n\t\tmutate(v)\n\t\treturn\n\t}\n\n\t// slow path for new keys\n\t// upgrade lock for adding new keys\n\tt.lock.RUnlock()\n\tt.lock.Lock()\n\tdefer t.lock.Unlock()\n\n\t// re-check for concurrent additions\n\tif v, ok := t.values[key]; ok {\n\t\tmutate(v)\n\t\treturn\n\t}\n\n\t// add new key\n\tvar v *V\n\tif t.new != nil {\n\t\tv = t.new()\n\t} else {\n\t\tv = new(V)\n\t}\n\n\tt.values[key] = v\n\tmutate(v)\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/experiment/tracker/website.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage tracker\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\tapiequality \"k8s.io/apimachinery/pkg/api/equality\"\n\t\"k8s.io/apimachinery/pkg/types\"\n\t\"k8s.io/client-go/util/workqueue\"\n\t\"sigs.k8s.io/controller-runtime/pkg/builder\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller\"\n\t\"sigs.k8s.io/controller-runtime/pkg/event\"\n\t\"sigs.k8s.io/controller-runtime/pkg/handler\"\n\tlogf \"sigs.k8s.io/controller-runtime/pkg/log\"\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\t\"sigs.k8s.io/controller-runtime/pkg/metrics\"\n\t\"sigs.k8s.io/controller-runtime/pkg/predicate\"\n\t\"sigs.k8s.io/controller-runtime/pkg/reconcile\"\n\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n)\n\nvar (\n\t// NOTE: upper bound 5 is the SLO. Align buckets with SLO so that when p99 estimation grows above SLO we are sure\n\t// that p99 is actually above SLO.\n\t// See https://prometheus.io/docs/practices/histograms/#errors-of-quantile-estimation\n\tbuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}\n\n\twebsiteReconciliationLatency = prometheus.NewHistogramVec(prometheus.HistogramOpts{\n\t\tNamespace: \"experiment\",\n\t\tSubsystem: \"website\",\n\t\tName:      \"reconciliation_duration_seconds\",\n\t\tHelp: \"Latency from Website creation or spec update until the generation is observed as ready by a watch. \" +\n\t\t\t\"This is an SLI for controller performance.\",\n\t\tBuckets: buckets,\n\t}, nil)\n\twebsiteBackfilledGenerations = prometheus.NewCounterVec(prometheus.CounterOpts{\n\t\tNamespace: \"experiment\",\n\t\tSubsystem: \"website\",\n\t\tName:      \"backfilled_generations_total\",\n\t\tHelp: \"Counter for Website generations that were never observed as ready before the next generation appeared. \" +\n\t\t\t\"For such generations, the time when the next generation got ready is used for calculating the reconciliation latency. \" +\n\t\t\t\"This metric serves as an indicator for how accurate the reconciliation latency measurement is.\",\n\t}, nil)\n\twatchLatency = prometheus.NewHistogramVec(prometheus.HistogramOpts{\n\t\tNamespace: \"experiment\",\n\t\tName:      \"watch_latency_seconds\",\n\t\tHelp: \"Latency from Website transition time until observed by a watch event in experiment. \" +\n\t\t\t\"This metric serves as an indicator for how experiment itself is performing to ensure accurate measurements.\",\n\t\tBuckets: buckets,\n\t}, nil)\n)\n\n// WebsiteTracker tracks how long it takes for generations of Website objects to be reconciled and get ready.\ntype WebsiteTracker struct {\n\treader client.Reader\n\n\t// objects maps an object's UID to the object's generation information.\n\t// The UID is used as the key instead of a namespaced name so that the tracker can distinguish between object\n\t// instances with the same namespaced name.\n\tobjects *tracker[types.UID, objectGenerations]\n}\n\n// objectGenerations stores information about all generations of a single object.\ntype objectGenerations struct {\n\tlock        sync.Mutex\n\tgenerations *tracker[int64, generationTimes]\n}\n\n// generationTimes stores information about a single generation of an object.\n// It doesn't synchronize access. Access is synchronized by the lock on objectGenerations level.\ntype generationTimes struct {\n\tcreated, ready time.Time\n\trecorded       bool\n}\n\nfunc newObjectsTracker() *tracker[types.UID, objectGenerations] {\n\treturn &tracker[types.UID, objectGenerations]{\n\t\tvalues: map[types.UID]*objectGenerations{},\n\t\tnew: func() *objectGenerations {\n\t\t\treturn &objectGenerations{\n\t\t\t\tgenerations: newGenerationsTracker(),\n\t\t\t}\n\t\t},\n\t}\n}\n\nfunc newGenerationsTracker() *tracker[int64, generationTimes] {\n\treturn &tracker[int64, generationTimes]{\n\t\tvalues: map[int64]*generationTimes{},\n\t}\n}\n\n// AddToManager initializes the tracker, registers its metrics, and starts watching objects.\nfunc (w *WebsiteTracker) AddToManager(mgr manager.Manager) error {\n\tif w.reader == nil {\n\t\tw.reader = mgr.GetCache()\n\t}\n\n\tw.objects = newObjectsTracker()\n\n\t// initialize counters\n\twebsiteBackfilledGenerations.WithLabelValues().Add(0)\n\n\t// register all metrics\n\tmetrics.Registry.MustRegister(websiteReconciliationLatency, websiteBackfilledGenerations, watchLatency)\n\n\treturn builder.ControllerManagedBy(mgr).\n\t\tNamed(\"website-tracker\").\n\t\tWatches(&webhostingv1alpha1.Website{}, w.websiteHandler(), builder.WithPredicates(w.observedNewReadyGeneration())).\n\t\tWithOptions(controller.Options{\n\t\t\tMaxConcurrentReconciles: 5,\n\t\t}).\n\t\tComplete(w)\n}\n\n// websiteHandler enqueues the object's UID for update requests.\n// It concurrently adds the observed status to the tracker and enqueues the object for reconciliation with a short delay\n// to give the tracker enough time to store the observed status.\n// This reduces the number of requeues we need to do for waiting for the ready timestamp to arrive in the tracker.\nfunc (w *WebsiteTracker) websiteHandler() handler.EventHandler {\n\treturn handler.Funcs{\n\t\tUpdateFunc: func(_ context.Context, e event.UpdateEvent, q workqueue.TypedRateLimitingInterface[reconcile.Request]) {\n\t\t\twebsite, ok := e.ObjectNew.(*webhostingv1alpha1.Website)\n\t\t\tif !ok {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tw.recordStatusGeneration(website)\n\n\t\t\tq.AddAfter(reconcile.Request{NamespacedName: types.NamespacedName{\n\t\t\t\tName: string(website.UID),\n\t\t\t}}, time.Second)\n\t\t},\n\t}\n}\n\n// observedNewReadyGeneration returns a predicate that triggers when a new generation is observed to be ready and its\n// reconciliation latency should be recorded by the reconciler.\nfunc (w *WebsiteTracker) observedNewReadyGeneration() predicate.Predicate {\n\treturn predicate.Funcs{\n\t\tCreateFunc: func(_ event.CreateEvent) bool { return false },\n\t\tUpdateFunc: func(e event.UpdateEvent) bool {\n\t\t\toldWebsite, ok := e.ObjectOld.(*webhostingv1alpha1.Website)\n\t\t\tif !ok {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\twebsite, ok := e.ObjectNew.(*webhostingv1alpha1.Website)\n\t\t\tif !ok {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\t// Record how long it took experiment to observe the transition.\n\t\t\tif t := website.Status.LastTransitionTime; t != nil && !t.Equal(oldWebsite.Status.LastTransitionTime) {\n\t\t\t\twatchLatency.WithLabelValues().Observe(time.Since(t.Time).Seconds())\n\t\t\t}\n\n\t\t\t// if the status changed and the website is ready, we observed a new generation becoming ready\n\t\t\treturn !apiequality.Semantic.DeepEqual(oldWebsite.Status, website.Status) &&\n\t\t\t\twebsite.Status.Phase == webhostingv1alpha1.PhaseReady\n\t\t},\n\t\tDeleteFunc:  func(_ event.DeleteEvent) bool { return false },\n\t\tGenericFunc: func(_ event.GenericEvent) bool { return false },\n\t}\n}\n\n// RecordSpecChange records a new generation of the given website as created or updated by the experiment.\n// Supposed to be called by the load generator.\nfunc (w *WebsiteTracker) RecordSpecChange(website *webhostingv1alpha1.Website) {\n\t// record time first, before locking\n\tt := time.Now()\n\n\t// store time concurrently, so that we don't block the load generator\n\tgo w.objects.set(website.UID, func(generations *objectGenerations) {\n\t\tgenerations.setGenerationCreated(website.Generation, t)\n\t})\n}\n\n// recordStatusGeneration records a new observed generation of the given website if it is ready.\n// Supposed to be called by the watch handler (synchronously).\nfunc (w *WebsiteTracker) recordStatusGeneration(website *webhostingv1alpha1.Website) {\n\t// record time first, before locking\n\tt := time.Now()\n\n\t// store time concurrently, so that we don't block the watch handler/reflector\n\tgo w.objects.set(website.UID, func(generations *objectGenerations) {\n\t\tgenerations.setGenerationReady(website.Status.ObservedGeneration, t)\n\t})\n}\n\n// setGenerationCreated records the time when the given generation was created, i.e., when the creation / spec change\n// happened.\nfunc (o *objectGenerations) setGenerationCreated(generation int64, t time.Time) {\n\to.lock.Lock()\n\tdefer o.lock.Unlock()\n\n\to.generations.set(generation, func(times *generationTimes) {\n\t\tif !times.created.IsZero() {\n\t\t\t// generation was already recorded\n\t\t\treturn\n\t\t}\n\n\t\ttimes.created = t\n\t})\n}\n\n// setGenerationReady records the time when the given generation was observed as ready.\nfunc (o *objectGenerations) setGenerationReady(generation int64, t time.Time) {\n\to.lock.Lock()\n\tdefer o.lock.Unlock()\n\n\to.generations.set(generation, func(times *generationTimes) {\n\t\tif !times.ready.IsZero() {\n\t\t\t// generation was already recorded\n\t\t\treturn\n\t\t}\n\n\t\ttimes.ready = t\n\t})\n}\n\n// Reconcile iterates over all objects and records metrics for the generations that were observed to be ready.\nfunc (w *WebsiteTracker) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {\n\tlog := logf.FromContext(ctx)\n\tuid := types.UID(req.Name)\n\n\tvar res reconcile.Result\n\tw.objects.set(uid, func(generations *objectGenerations) {\n\t\tres = generations.reconcile(log)\n\t})\n\treturn res, nil\n}\n\n// reconcile iterates over the object's generations and records newly observed finished reconciliations in the latency\n// metric.\nfunc (o *objectGenerations) reconcile(log logr.Logger) reconcile.Result {\n\to.lock.Lock()\n\tdefer o.lock.Unlock()\n\n\tgenerations := generationsList(o.generations.sortedValues())\n\tgenerations.backfillGenerations()\n\n\tif finished := generations.recordNewReadyGenerations(log); !finished {\n\t\treturn reconcile.Result{Requeue: true}\n\t}\n\n\treturn reconcile.Result{}\n}\n\ntype generationsList []*generationTimes\n\n// backfillGenerations backfills the ready time for generations if we observed a newer ready generation.\n// This might be necessary if we missed some watch events, or multiple generations were created in quick succession\n// where only a later one was reconciled by the controller to be ready.\n// The generations slice must be sorted by generation in ascending order.\nfunc (gg generationsList) backfillGenerations() {\n\tvar newerReadyTime time.Time\n\tfor i := len(gg) - 1; i >= 0; i-- {\n\t\tg := gg[i]\n\n\t\tif g.recorded {\n\t\t\tcontinue\n\t\t}\n\n\t\tif g.ready.IsZero() {\n\t\t\t// this generation was not observed as ready,\n\t\t\t// copy the ready time from the generation after it (if it has been observed as ready)\n\t\t\tg.ready = newerReadyTime\n\t\t\twebsiteBackfilledGenerations.WithLabelValues().Add(1)\n\t\t} else {\n\t\t\t// this generation was observed as ready, copy the timestamp for backfilling earlier generations.\n\t\t\tnewerReadyTime = g.ready\n\t\t}\n\t}\n}\n\n// recordNewReadyGenerations records all newly observed ready generations.\n// Returns true if all generations have been recorded, false if there are unready generations left.\nfunc (gg generationsList) recordNewReadyGenerations(log logr.Logger) bool {\n\tfinished := true\n\tfor _, g := range gg {\n\t\tif g.recorded {\n\t\t\tcontinue\n\t\t}\n\t\tif g.created.IsZero() || g.ready.IsZero() {\n\t\t\tfinished = false\n\t\t\tcontinue\n\t\t}\n\n\t\tlatency := g.ready.Sub(g.created)\n\t\tlogLevel := 1\n\t\tif latency > 30*time.Second {\n\t\t\tlogLevel = 0\n\t\t}\n\t\tlog.V(logLevel).Info(\"Observed ready website\", \"latency\", latency, \"created\", g.created, \"ready\", g.ready)\n\n\t\twebsiteReconciliationLatency.WithLabelValues().Observe(latency.Seconds())\n\t\tg.recorded = true\n\t}\n\n\treturn finished\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/metrics/add.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage metrics\n\nimport (\n\t\"fmt\"\n\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n)\n\nconst namespace = \"kube\"\n\n// AddToManager adds all metrics exporters for webhosting objects to the manager.\nfunc AddToManager(mgr manager.Manager) error {\n\tif err := WebsiteExporter.AddToManager(mgr); err != nil {\n\t\treturn fmt.Errorf(\"failed to add website exporter: %w\", err)\n\t}\n\n\tif err := ThemeExporter.AddToManager(mgr); err != nil {\n\t\treturn fmt.Errorf(\"failed to add theme exporter: %w\", err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/metrics/theme.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage metrics\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/metrics/exporter\"\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n)\n\nvar ThemeExporter = exporter.Exporter[*webhostingv1alpha1.Theme, *webhostingv1alpha1.ThemeList]{\n\tNamespace: namespace,\n\tSubsystem: \"theme\",\n\n\tStaticLabelKeys: []string{\"theme\", \"uid\"},\n\tGenerateStaticLabelValues: func(theme *webhostingv1alpha1.Theme) []string {\n\t\treturn []string{theme.Name, string(theme.UID)}\n\t},\n\n\tMetrics: []exporter.Metric[*webhostingv1alpha1.Theme]{\n\t\t{\n\t\t\tName:      \"info\",\n\t\t\tHelp:      \"Information about a Theme\",\n\t\t\tLabelKeys: []string{\"color\", \"font_family\"},\n\n\t\t\tGenerate: func(desc *prometheus.Desc, theme *webhostingv1alpha1.Theme, staticLabelValues []string, ch chan<- prometheus.Metric) {\n\t\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\t\tdesc,\n\t\t\t\t\tprometheus.GaugeValue,\n\t\t\t\t\t1,\n\t\t\t\t\tappend(staticLabelValues, theme.Spec.Color, theme.Spec.FontFamily)...,\n\t\t\t\t)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName: \"metadata_generation\",\n\t\t\tHelp: \"The generation of a Theme\",\n\n\t\t\tGenerate: func(desc *prometheus.Desc, theme *webhostingv1alpha1.Theme, staticLabelValues []string, ch chan<- prometheus.Metric) {\n\t\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\t\tdesc,\n\t\t\t\t\tprometheus.GaugeValue,\n\t\t\t\t\tfloat64(theme.Generation),\n\t\t\t\t\tstaticLabelValues...,\n\t\t\t\t)\n\t\t\t},\n\t\t},\n\t},\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/metrics/website.go",
    "content": "/*\nCopyright 2024 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage metrics\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/metrics/exporter\"\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n)\n\nvar WebsiteExporter = exporter.Exporter[*webhostingv1alpha1.Website, *webhostingv1alpha1.WebsiteList]{\n\tNamespace: namespace,\n\tSubsystem: \"website\",\n\n\tStaticLabelKeys: []string{\"namespace\", \"website\", \"uid\"},\n\tGenerateStaticLabelValues: func(website *webhostingv1alpha1.Website) []string {\n\t\treturn []string{website.Namespace, website.Name, string(website.UID)}\n\t},\n\n\tMetrics: []exporter.Metric[*webhostingv1alpha1.Website]{\n\t\t{\n\t\t\tName:      \"info\",\n\t\t\tHelp:      \"Information about a Website\",\n\t\t\tLabelKeys: []string{\"theme\"},\n\n\t\t\tGenerate: func(desc *prometheus.Desc, website *webhostingv1alpha1.Website, staticLabelValues []string, ch chan<- prometheus.Metric) {\n\t\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\t\tdesc,\n\t\t\t\t\tprometheus.GaugeValue,\n\t\t\t\t\t1,\n\t\t\t\t\tappend(staticLabelValues, website.Spec.Theme)...,\n\t\t\t\t)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName:      \"shard\",\n\t\t\tHelp:      \"Sharding information about a Website\",\n\t\t\tLabelKeys: []string{\"shard\", \"drain\"},\n\n\t\t\tGenerate: func(desc *prometheus.Desc, website *webhostingv1alpha1.Website, staticLabelValues []string, ch chan<- prometheus.Metric) {\n\t\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\t\tdesc,\n\t\t\t\t\tprometheus.GaugeValue,\n\t\t\t\t\t1,\n\t\t\t\t\tappend(staticLabelValues,\n\t\t\t\t\t\twebsite.Labels[shardingv1alpha1.LabelShard(webhostingv1alpha1.WebhostingOperatorName)],\n\t\t\t\t\t\twebsite.Labels[shardingv1alpha1.LabelDrain(webhostingv1alpha1.WebhostingOperatorName)],\n\t\t\t\t\t)...,\n\t\t\t\t)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName: \"metadata_generation\",\n\t\t\tHelp: \"The generation of a Website\",\n\n\t\t\tGenerate: func(desc *prometheus.Desc, website *webhostingv1alpha1.Website, staticLabelValues []string, ch chan<- prometheus.Metric) {\n\t\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\t\tdesc,\n\t\t\t\t\tprometheus.GaugeValue,\n\t\t\t\t\tfloat64(website.Generation),\n\t\t\t\t\tstaticLabelValues...,\n\t\t\t\t)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName: \"observed_generation\",\n\t\t\tHelp: \"The latest generation observed by the Website controller\",\n\n\t\t\tGenerate: func(desc *prometheus.Desc, website *webhostingv1alpha1.Website, staticLabelValues []string, ch chan<- prometheus.Metric) {\n\t\t\t\tch <- prometheus.MustNewConstMetric(\n\t\t\t\t\tdesc,\n\t\t\t\t\tprometheus.GaugeValue,\n\t\t\t\t\tfloat64(website.Status.ObservedGeneration),\n\t\t\t\t\tstaticLabelValues...,\n\t\t\t\t)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName:      \"status_phase\",\n\t\t\tHelp:      \"The Website's current phase (StateSet)\",\n\t\t\tLabelKeys: []string{\"phase\"},\n\n\t\t\tGenerate: exporter.GenerateStateSet[*webhostingv1alpha1.Website](\n\t\t\t\texporter.KnownStates(webhostingv1alpha1.AllWebsitePhases), nil,\n\t\t\t\tfunc(website *webhostingv1alpha1.Website) string {\n\t\t\t\t\treturn string(website.Status.Phase)\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t},\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/utils/kubernetes.go",
    "content": "/*\nCopyright 2023 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage utils\n\nimport (\n\t\"os\"\n\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n)\n\n// RunningInCluster implements a heuristic for determining whether the process is running in a cluster or not.\nfunc RunningInCluster() bool {\n\t_, err := os.Stat(\"/var/run/secrets/kubernetes.io/serviceaccount/namespace\")\n\tif err == nil {\n\t\treturn true\n\t}\n\n\treturn os.Getenv(\"KUBERNETES_SERVICE_HOST\") != \"\"\n}\n\n// IsDeploymentReady returns true if the current generation has been observed by the deployment controller and has been\n// fully rolled out.\nfunc IsDeploymentReady(deployment *appsv1.Deployment) bool {\n\tif deployment.Status.ObservedGeneration < deployment.Generation {\n\t\treturn false\n\t}\n\n\tavailable := GetDeploymentCondition(deployment.Status.Conditions, appsv1.DeploymentAvailable)\n\tif available == nil || available.Status != corev1.ConditionTrue {\n\t\treturn false\n\t}\n\n\tprogressing := GetDeploymentCondition(deployment.Status.Conditions, appsv1.DeploymentProgressing)\n\tif progressing == nil || progressing.Status != corev1.ConditionTrue || progressing.Reason != \"NewReplicaSetAvailable\" {\n\t\t// only if Progressing is in status True with reason NewReplicaSetAvailable, the Deployment has been fully rolled out\n\t\t// note: old pods or excess pods (scale-down) might still be terminating, but there is no way to tell this from the\n\t\t// Deployment's status, see https://github.com/kubernetes/kubernetes/issues/110171\n\t\treturn false\n\t}\n\n\treturn true\n}\n\n// GetDeploymentCondition returns the condition with the given type or nil, if it is not included.\nfunc GetDeploymentCondition(conditions []appsv1.DeploymentCondition, conditionType appsv1.DeploymentConditionType) *appsv1.DeploymentCondition {\n\tfor _, cond := range conditions {\n\t\tif cond.Type == conditionType {\n\t\t\treturn &cond\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "webhosting-operator/pkg/utils/utils.go",
    "content": "/*\nCopyright 2022 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage utils\n\nimport (\n\t\"math/rand\"\n)\n\n// PickRandom picks a random element from the given slice.\nfunc PickRandom[T any](in []T) T {\n\t// nolint:gosec // doesn't need to be cryptographically secure\n\treturn in[rand.Intn(len(in))]\n}\n\n// RandomName generates a random string with n characters that can be used as part of API object names.\nfunc RandomName(n int) string {\n\tconst charset = \"abcdefghijklmnopqrstuvwxyz\"\n\tresult := make([]byte, n)\n\tfor i := range result {\n\t\t// nolint:gosec // doesn't need to be cryptographically secure\n\t\tresult[i] = charset[rand.Intn(len(charset))]\n\t}\n\treturn string(result)\n}\n"
  },
  {
    "path": "webhosting-operator/test/e2e/e2e_suite_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage e2e\n\nimport (\n\t\"context\"\n\t\"flag\"\n\t\"maps\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\tclientgoscheme \"k8s.io/client-go/kubernetes/scheme\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client/config\"\n\t\"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil\"\n\t\"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\t\"sigs.k8s.io/controller-runtime/pkg/log/zap\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n)\n\nvar skipCleanup bool\n\nfunc TestMain(m *testing.M) {\n\tflag.BoolVar(&skipCleanup, \"skip-cleanup\", false, \"Skip cleanup after test failure\")\n\tflag.Parse()\n\tm.Run()\n}\n\nfunc TestE2E(t *testing.T) {\n\tRegisterFailHandler(Fail)\n\tRunSpecs(t, \"Webhosting Operator E2E Test Suite\")\n}\n\nconst (\n\ttestID = \"e2e-webhosting-operator\"\n\n\tShortTimeout  = 10 * time.Second\n\tMediumTimeout = time.Minute\n)\n\nvar (\n\tlog logr.Logger\n\n\ttestClient client.Client\n\n\ttestRunID     string\n\ttestRunLabels map[string]string\n)\n\nvar _ = BeforeSuite(func() {\n\tlog = zap.New(zap.UseDevMode(true), zap.WriteTo(GinkgoWriter)).WithName(testID)\n\n\trestConfig, err := config.GetConfig()\n\tExpect(err).NotTo(HaveOccurred())\n\n\tscheme := runtime.NewScheme()\n\tschemeBuilder := runtime.NewSchemeBuilder(\n\t\tclientgoscheme.AddToScheme,\n\t\tshardingv1alpha1.AddToScheme,\n\t\twebhostingv1alpha1.AddToScheme,\n\t)\n\tExpect(schemeBuilder.AddToScheme(scheme)).To(Succeed())\n\n\ttestClient, err = client.New(restConfig, client.Options{Scheme: scheme})\n\tExpect(err).NotTo(HaveOccurred())\n\n\tclientContext, clientCancel := context.WithCancel(context.Background())\n\tkomega.SetClient(testClient)\n\tkomega.SetContext(clientContext)\n\tDeferCleanup(clientCancel)\n\n\ttestRunID = testID + \"-\" + test.RandomSuffix()\n\ttestRunLabels = map[string]string{\n\t\ttestID: testRunID,\n\t}\n\tlog = log.WithValues(\"testRun\", testRunID)\n})\n\nvar (\n\tcontrollerRing *shardingv1alpha1.ControllerRing\n\tnamespace      *corev1.Namespace\n\n\tcontrollerDeployment *appsv1.Deployment\n)\n\nvar _ = BeforeEach(func(ctx SpecContext) {\n\tBy(\"Set up test Namespace\")\n\tnamespace = &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{\n\t\tGenerateName: testRunID + \"-\",\n\t\tLabels:       maps.Clone(testRunLabels),\n\t}}\n\tnamespace.Labels[webhostingv1alpha1.LabelKeyProject] = webhostingv1alpha1.LabelValueProject\n\n\t// We create a dedicated test namespace and clean it up for every test case to ensure a clean test environment.\n\tExpect(testClient.Create(ctx, namespace)).To(Succeed())\n\tlog.Info(\"Created test Namespace\", \"namespace\", namespace.Name)\n\n\tDeferCleanup(func(ctx SpecContext) {\n\t\tif ctx.SpecReport().Failed() && skipCleanup {\n\t\t\tSkip(\"Leaving state of test failure because --skip-cleanup is set to true\")\n\t\t}\n\n\t\tBy(\"Delete all Websites in test Namespace\")\n\t\tExpect(testClient.DeleteAllOf(ctx, &webhostingv1alpha1.Website{}, client.InNamespace(namespace.Name))).To(Succeed())\n\n\t\tBy(\"Delete test Namespace\")\n\t\tEventually(ctx, func() error {\n\t\t\treturn testClient.Delete(ctx, namespace)\n\t\t}).Should(Or(Succeed(), BeNotFoundError()))\n\t}, NodeTimeout(MediumTimeout))\n\n\tBy(\"Set up test ControllerRing\")\n\tcontrollerRing = &shardingv1alpha1.ControllerRing{ObjectMeta: metav1.ObjectMeta{Name: webhostingv1alpha1.WebhostingOperatorName}}\n\n\tBy(\"Scaling webhosting-operator\")\n\tcontrollerDeployment = &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: webhostingv1alpha1.WebhostingOperatorName, Namespace: webhostingv1alpha1.NamespaceSystem}}\n\tscaleController(ctx, 3)\n\n\tDeferCleanup(func(ctx SpecContext) {\n\t\tif ctx.SpecReport().Failed() && skipCleanup {\n\t\t\tSkip(\"Leaving state of test failure because --skip-cleanup is set to true\")\n\t\t}\n\n\t\tBy(\"Scaling webhosting-operator\")\n\t\tscaleController(ctx, 3)\n\t}, NodeTimeout(ShortTimeout))\n\n\tBy(\"Set up test Theme\")\n\ttheme = &webhostingv1alpha1.Theme{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:   namespace.Name,\n\t\t\tLabels: maps.Clone(testRunLabels),\n\t\t},\n\t\tSpec: webhostingv1alpha1.ThemeSpec{\n\t\t\tColor:      \"cyan\",\n\t\t\tFontFamily: \"arial\",\n\t\t},\n\t}\n\tExpect(controllerutil.SetOwnerReference(namespace, theme, testClient.Scheme(), controllerutil.WithBlockOwnerDeletion(true))).To(Succeed())\n\tExpect(testClient.Create(ctx, theme)).To(Succeed())\n}, NodeTimeout(MediumTimeout), OncePerOrdered)\n"
  },
  {
    "path": "webhosting-operator/test/e2e/webhosting_operator_test.go",
    "content": "/*\nCopyright 2025 Tim Ebert.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage e2e\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"maps\"\n\t\"strconv\"\n\n\t. \"github.com/onsi/ginkgo/v2\"\n\t. \"github.com/onsi/gomega\"\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tautoscalingv1 \"k8s.io/api/autoscaling/v1\"\n\tcoordinationv1 \"k8s.io/api/coordination/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tnetworkingv1 \"k8s.io/api/networking/v1\"\n\t\"k8s.io/apimachinery/pkg/api/meta\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/apimachinery/pkg/util/sets\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client\"\n\t\"sigs.k8s.io/controller-runtime/pkg/client/apiutil\"\n\t. \"sigs.k8s.io/controller-runtime/pkg/envtest/komega\"\n\n\tshardingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/pkg/apis/sharding/v1alpha1\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/sharding/leases\"\n\t\"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test\"\n\t. \"github.com/timebertt/kubernetes-controller-sharding/pkg/utils/test/matchers\"\n\twebhostingv1alpha1 \"github.com/timebertt/kubernetes-controller-sharding/webhosting-operator/pkg/apis/webhosting/v1alpha1\"\n)\n\nconst objectCount = 100\n\nvar (\n\tmainObject        = &webhostingv1alpha1.Website{}\n\tcontrolledObjects = []client.Object{\n\t\t&appsv1.Deployment{},\n\t\t&corev1.ConfigMap{},\n\t\t&corev1.Service{},\n\t\t&networkingv1.Ingress{},\n\t}\n)\n\nvar theme *webhostingv1alpha1.Theme\n\nvar _ = Describe(\"Webhosting Operator\", Label(webhostingv1alpha1.WebhostingOperatorName), func() {\n\tDescribe(\"setup\", Ordered, func() {\n\t\titDeploymentShouldBeAvailable(3)\n\t\titControllerRingShouldHaveAvailableShards(3)\n\t\titShouldRecognizeReadyShardLeases(3)\n\t})\n\n\tDescribe(\"creating a website\", Ordered, func() {\n\t\tvar (\n\t\t\twebsite *webhostingv1alpha1.Website\n\t\t\tshard   string\n\t\t)\n\n\t\titControllerRingShouldHaveAvailableShards(3)\n\t\titShouldRecognizeReadyShardLeases(3)\n\n\t\tIt(\"should assign the main object to a healthy shard\", func(ctx SpecContext) {\n\t\t\t// Verify that the sharder successfully injects the shard label.\n\t\t\t// The webhook has failurePolicy=Ignore, so we might need to retry the creation until the injection succeeds.\n\t\t\tEventually(ctx, func(g Gomega) *webhostingv1alpha1.Website {\n\t\t\t\twebsite = newWebsite(\"foo-\" + test.RandomSuffix())\n\t\t\t\tg.Expect(testClient.Create(ctx, website)).To(Succeed())\n\t\t\t\treturn website\n\t\t\t}).Should(And(\n\t\t\t\tHaveLabelWithValue(controllerRing.LabelShard(), BeElementOf(shards)),\n\t\t\t\tNot(HaveLabel(controllerRing.LabelDrain())),\n\t\t\t))\n\t\t\tshard = website.Labels[controllerRing.LabelShard()]\n\n\t\t\tlog.Info(\"Created object\", \"website\", client.ObjectKeyFromObject(website), \"shard\", shard)\n\t\t}, SpecTimeout(MediumTimeout))\n\n\t\tfor _, obj := range controlledObjects {\n\t\t\tIt(fmt.Sprintf(\"should assign the controlled %T to the same shard\", obj), func(ctx SpecContext) {\n\t\t\t\tEventually(ctx, ObjectList(listOf(obj), client.InNamespace(namespace.Name), client.MatchingLabels{\"website\": website.Name})).\n\t\t\t\t\tShould(HaveField(\"Items\", ConsistOf(And(\n\t\t\t\t\t\tHaveLabelWithValue(controllerRing.LabelShard(), Equal(shard)),\n\t\t\t\t\t\tNot(HaveLabel(controllerRing.LabelDrain())),\n\t\t\t\t\t))))\n\t\t\t}, SpecTimeout(MediumTimeout))\n\t\t}\n\n\t\titWebsitesShouldBeReady()\n\t})\n\n\tdescribeScaleController(\"adding a shard\", 4)\n\n\tdescribeScaleController(\"removing a shard\", 2)\n})\n\nfunc describeScaleController(text string, replicas int32) {\n\tDescribe(text, Ordered, func() {\n\t\titControllerRingShouldHaveAvailableShards(3)\n\t\titShouldRecognizeReadyShardLeases(3)\n\n\t\titCreateWebsites()\n\t\titShouldAssignObjectsToAvailableShards()\n\t\titWebsitesShouldBeReady()\n\n\t\titScaleController(replicas)\n\t\titDeploymentShouldBeAvailable(replicas)\n\t\titControllerRingShouldHaveAvailableShards(replicas)\n\t\titShouldRecognizeReadyShardLeases(int(replicas))\n\n\t\titShouldAssignObjectsToAvailableShards()\n\t\titWebsitesShouldBeReady()\n\t})\n}\n\nfunc newWebsite(name string) *webhostingv1alpha1.Website {\n\tlabels := maps.Clone(testRunLabels)\n\tlabels[webhostingv1alpha1.LabelKeySkipWorkload] = \"true\"\n\n\treturn &webhostingv1alpha1.Website{\n\t\tObjectMeta: metav1.ObjectMeta{\n\t\t\tName:      name,\n\t\t\tNamespace: namespace.Name,\n\t\t\tLabels:    labels,\n\t\t},\n\t\tSpec: webhostingv1alpha1.WebsiteSpec{\n\t\t\tTheme: theme.Name,\n\t\t},\n\t}\n}\n\nfunc itDeploymentShouldBeAvailable(expectedReplicas int32) {\n\tGinkgoHelper()\n\n\tIt(fmt.Sprintf(\"the %s Deployment should be available\", webhostingv1alpha1.WebhostingOperatorName), func(ctx SpecContext) {\n\t\tEventually(ctx, Object(controllerDeployment)).Should(And(\n\t\t\tHaveField(\"Spec.Replicas\", HaveValue(BeEquivalentTo(expectedReplicas))),\n\t\t\tHaveField(\"Status.Replicas\", BeEquivalentTo(expectedReplicas)),\n\t\t\tHaveField(\"Status.AvailableReplicas\", BeEquivalentTo(expectedReplicas)),\n\t\t))\n\t}, SpecTimeout(MediumTimeout))\n}\n\nfunc itControllerRingShouldHaveAvailableShards(expectedAvailableShards int32) {\n\tGinkgoHelper()\n\n\tIt(fmt.Sprintf(\"the ControllerRing should be ready and should have %d available shards\", expectedAvailableShards), func(ctx SpecContext) {\n\t\tEventually(ctx, Object(controllerRing)).Should(And(\n\t\t\tHaveField(\"Status.AvailableShards\", BeEquivalentTo(expectedAvailableShards)),\n\t\t\tHaveField(\"Status.Conditions\", ConsistOf(\n\t\t\t\tMatchCondition(\n\t\t\t\t\tOfType(shardingv1alpha1.ControllerRingReady),\n\t\t\t\t\tWithStatus(metav1.ConditionTrue),\n\t\t\t\t),\n\t\t\t)),\n\t\t))\n\t}, SpecTimeout(MediumTimeout))\n}\n\nvar shards []string\n\nfunc itShouldRecognizeReadyShardLeases(expectedCount int) {\n\tGinkgoHelper()\n\n\tIt(fmt.Sprintf(\"should recognize %d ready shard leases\", expectedCount), func(ctx SpecContext) {\n\t\tleaseList := &coordinationv1.LeaseList{}\n\t\tEventually(ctx, ObjectList(leaseList, client.InNamespace(controllerDeployment.Namespace), client.MatchingLabels{\n\t\t\tshardingv1alpha1.LabelControllerRing: controllerRing.Name,\n\t\t\tshardingv1alpha1.LabelState:          leases.Ready.String(),\n\t\t})).Should(HaveField(\"Items\", HaveLen(expectedCount)))\n\n\t\tshards = make([]string, len(leaseList.Items))\n\t\tfor i, lease := range leaseList.Items {\n\t\t\tshards[i] = lease.Name\n\t\t}\n\t}, SpecTimeout(ShortTimeout))\n}\n\nfunc itCreateWebsites() {\n\tGinkgoHelper()\n\n\tIt(fmt.Sprintf(\"create %d websites\", objectCount), func(ctx SpecContext) {\n\t\tfor i := 0; i < objectCount; i++ {\n\t\t\twebsite := newWebsite(\"foo-\" + strconv.Itoa(i))\n\t\t\tExpect(testClient.Create(ctx, website)).To(Succeed(), \"should create website %s\", website.Name)\n\t\t}\n\t}, SpecTimeout(MediumTimeout))\n}\n\nfunc itWebsitesShouldBeReady() {\n\tGinkgoHelper()\n\n\tIt(\"all Websites should be ready\", func(ctx SpecContext) {\n\t\tEventually(ctx, ObjectList(&webhostingv1alpha1.WebsiteList{}, client.InNamespace(namespace.Name))).Should(\n\t\t\tHaveField(\"Items\", HaveEach(\n\t\t\t\tHaveField(\"Status.Phase\", webhostingv1alpha1.PhaseReady),\n\t\t\t)),\n\t\t)\n\t}, SpecTimeout(MediumTimeout))\n}\n\nfunc itScaleController(replicas int32) {\n\tGinkgoHelper()\n\n\tIt(fmt.Sprintf(\"scale the controller to %d replicas\", replicas), func(ctx SpecContext) {\n\t\tscaleController(ctx, replicas)\n\t}, NodeTimeout(ShortTimeout))\n}\n\nfunc scaleController(ctx context.Context, replicas int32) {\n\tGinkgoHelper()\n\n\tpatch := client.MergeFrom(&autoscalingv1.Scale{})\n\tscale := &autoscalingv1.Scale{Spec: autoscalingv1.ScaleSpec{Replicas: replicas}}\n\tExpect(testClient.SubResource(\"scale\").Patch(ctx, controllerDeployment, patch, client.WithSubResourceBody(scale), &client.SubResourcePatchOptions{})).To(Succeed())\n\n\tlog.Info(\"Scaled controller\", \"replicas\", replicas)\n}\n\nfunc itShouldAssignObjectsToAvailableShards() {\n\tGinkgoHelper()\n\n\tfor _, obj := range append([]client.Object{mainObject}, controlledObjects...) {\n\t\tIt(fmt.Sprintf(\"should assign the %Ts to the available shards\", obj), func(ctx SpecContext) {\n\t\t\teventuallyShouldAssignObjectsToAvailableShards(ctx, obj)\n\t\t}, NodeTimeout(MediumTimeout))\n\t}\n}\n\nfunc eventuallyShouldAssignObjectsToAvailableShards(ctx context.Context, obj client.Object) {\n\tGinkgoHelper()\n\n\tEventually(ctx, func(g Gomega) {\n\t\tlist := listOf(obj)\n\t\tg.Expect(ObjectList(list, client.InNamespace(namespace.Name), client.MatchingLabels(testRunLabels))()).To(HaveField(\"Items\", HaveLen(objectCount)))\n\n\t\tusedShards := sets.New[string]()\n\t\tExpect(meta.EachListItem(list, func(obj runtime.Object) error {\n\t\t\tg.Expect(obj).To(HaveLabelWithValue(controllerRing.LabelShard(), Not(BeEmpty())), \"object %T %s should be assigned\")\n\t\t\tg.Expect(obj).NotTo(HaveLabel(controllerRing.LabelDrain()), \"object %T %s should not have drain label\")\n\n\t\t\tusedShards.Insert(obj.(client.Object).GetLabels()[controllerRing.LabelShard()])\n\t\t\treturn nil\n\t\t})).To(Succeed())\n\n\t\tg.Expect(usedShards.UnsortedList()).To(ConsistOf(shards), \"should use all available shards\")\n\t}).Should(Succeed())\n}\n\nfunc listOf(obj client.Object) client.ObjectList {\n\tgvk, err := apiutil.GVKForObject(obj, testClient.Scheme())\n\tExpect(err).NotTo(HaveOccurred())\n\n\tgvk.Kind += \"List\"\n\tlist, err := testClient.Scheme().New(gvk)\n\tExpect(err).NotTo(HaveOccurred())\n\treturn list.(client.ObjectList)\n}\n"
  }
]