[
  {
    "path": ".conform.yaml",
    "content": "# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.\n#\n# Generated on 2022-03-23T19:45:28Z by kres latest.\n\n---\npolicies:\n- type: commit\n  spec:\n    dco: true\n    gpg:\n      required: true\n      identity:\n        gitHubOrganization: siderolabs\n    spellcheck:\n      locale: US\n    maximumOfOneCommit: true\n    header:\n      length: 89\n      imperative: true\n      case: lower\n      invalidLastCharacters: .\n    body:\n      required: true\n    conventional:\n      types: [\"chore\",\"docs\",\"perf\",\"refactor\",\"style\",\"test\",\"release\"]\n      scopes: [\".*\"]"
  },
  {
    "path": ".github/renovate.json",
    "content": "{\n    \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n    \"extends\": [\n        \":semanticCommitScopeDisabled\",\n        \"schedule:earlyMondays\"\n    ],\n    \"packageRules\": [\n        {\n            \"matchDatasources\": [\n                \"go\",\n                \"golang-version\"\n            ],\n            \"groupName\": \"go packages\",\n            \"matchPackageNames\": [\n                \"*\"\n            ]\n        }\n    ],\n    \"dependencyDashboard\": true\n}\n"
  },
  {
    "path": ".github/workflows/acceptance-tests.yaml",
    "content": "name: acceptance-tests\nconcurrency:\n  group: ${{ github.head_ref || github.run_id }}\n  cancel-in-progress: true\non:\n  pull_request:\n    paths:\n      - 'go.mod'\n      - 'go.sum'\n      - '**.go'\njobs:\n  acc-tests:\n    if: (!startsWith(github.head_ref, 'renovate/') && !startsWith(github.head_ref, 'dependabot/'))\n    runs-on:\n      group: large\n    env:\n      GOTOOLCHAIN: local\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n      - name: Set up Go\n        uses: actions/setup-go@v5\n        with:\n          go-version-file: 'go.mod'\n          cache: true\n      - name: Set up Terraform\n        uses: hashicorp/setup-terraform@v3\n        with:\n          terraform_wrapper: false\n      - name: Set up libvirt\n        env:\n          LIBVIRT_DEFAULT_URI: qemu:///system\n        run: |\n          sudo apt-get update\n          sudo apt-get install -y \\\n            bridge-utils \\\n            dnsmasq-base \\\n            libvirt-daemon-system \\\n            qemu-utils \\\n            qemu-block-extra \\\n            ovmf\n\n          sudo ln -s OVMF_VARS_4M.fd /usr/share/OVMF/OVMF_VARS.fd\n          sudo ln -s OVMF_CODE_4M.fd /usr/share/OVMF/OVMF_CODE.fd\n\n          sudo virtlockd -d\n          sudo virtlogd -d\n          sudo libvirtd -d\n          echo -e \"<pool type='dir'>\\n<name>default</name>\\n<target>\\n<path>/pool-default</path>\\n</target>\\n</pool>\" > pool.xml\n          sudo mkdir /pool-default\n          sudo chmod a+rwx /pool-default\n          sudo virsh pool-define pool.xml\n          sudo virsh pool-start default\n          echo 'security_driver = \"none\"' | sudo tee --append /etc/libvirt/qemu.conf\n          cat <<EOF > net.xml\n          <network>\n            <name>default</name>\n            <bridge name='virbr0'/>\n            <mtu size=\"1350\"/>\n            <forward/>\n            <ip address='192.168.122.1' netmask='255.255.255.0'>\n              <dhcp>\n                <range start='192.168.122.2' end='192.168.122.254'/>\n              </dhcp>\n            </ip>\n          </network>\n          EOF\n          sudo virsh net-destroy default\n          sudo virsh net-undefine default\n          sudo virsh net-create net.xml\n      - name: acceptance-test\n        env:\n          TERRAFORM_LIBVIRT_TEST_DOMAIN_TYPE: qemu\n          LIBVIRT_DEFAULT_URI: qemu:///system\n          CI: \"true\"\n        run: |\n          make testacc\n"
  },
  {
    "path": ".github/workflows/pull-request.yaml",
    "content": "name: check-dirty\non:\n  pull_request:\njobs:\n  check-dirty:\n    if: (!startsWith(github.head_ref, 'renovate/') && !startsWith(github.head_ref, 'dependabot/'))\n    runs-on:\n      group: generic\n    env:\n      GOTOOLCHAIN: local\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n      - name: Set up Go\n        uses: actions/setup-go@v5\n        with:\n          go-version-file: 'go.mod'\n          cache: true\n      - name: Go vulnerability check\n        run: make go-vulncheck\n      - name: Set up Terraform\n        uses: hashicorp/setup-terraform@v3\n        with:\n          terraform_wrapper: false\n      - name: dirty-check\n        run: |\n          make check-dirty\n      - name: golangci-lint\n        uses: golangci/golangci-lint-action@v8\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "# This GitHub action can publish assets for release when a tag is created.\n# Currently its setup to run on any tag that matches the pattern \"v*\" (ie. v0.1.0).\n#\n# This uses an action (hashicorp/ghaction-import-gpg) that assumes you set your\n# private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE`\n# secret. If you would rather own your own GPG handling, please fork this action\n# or use an alternative one for key handling.\n#\n# You will need to pass the `--batch` flag to `gpg` in your signing step\n# in `goreleaser` to indicate this is being used in a non-interactive mode.\n#\nname: release\non:\n  push:\n    tags:\n      - 'v*'\npermissions:\n  contents: write\njobs:\n  goreleaser:\n    runs-on:\n      group: generic\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n      - name: Unshallow\n        run: git fetch --prune --unshallow\n      - name: Set up Go\n        uses: actions/setup-go@v5\n        with:\n          go-version-file: 'go.mod'\n          cache: true\n      - name: Import GPG key\n        uses: crazy-max/ghaction-import-gpg@v6\n        id: import_gpg\n        with:\n          gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}\n          passphrase: ${{ secrets.PASSPHRASE }}\n      - name: release-notes\n        run: make release-notes\n      - name: Generate SBOM\n        run: make sbom\n      - name: Run GoReleaser\n        uses: goreleaser/goreleaser-action@v6\n        with:\n          version: latest\n          args: release --clean --release-notes=_out/RELEASE_NOTES.md\n        env:\n          GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}\n          # GitHub sets this automatically\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/slack-notify.yaml",
    "content": "name: slack-notify\n\"on\":\n  workflow_run:\n    workflows:\n      - check-dirty\n      - acceptance-tests\n      - release\n    types:\n      - completed\njobs:\n  slack-notify:\n    runs-on:\n      group: generic\n    if: github.event.workflow_run.conclusion != 'skipped'\n    steps:\n      - name: Get PR number\n        id: get-pr-number\n        if: github.event.workflow_run.event == 'pull_request'\n        env:\n          GH_TOKEN: ${{ github.token }}\n        run: |\n          echo pull_request_number=$(gh pr view -R ${{ github.repository }} ${{ github.event.workflow_run.head_repository.owner.login }}:${{ github.event.workflow_run.head_branch }} --json number --jq .number) >> $GITHUB_OUTPUT\n      - name: Slack Notify\n        uses: slackapi/slack-github-action@v2\n        with:\n          method: chat.postMessage\n          payload: |\n            {\n                \"channel\": \"proj-talos-maintainers\",\n                \"attachments\": [\n                    {\n                        \"color\": \"${{ github.event.workflow_run.conclusion == 'success' && '#2EB886' || github.event.workflow_run.conclusion == 'failure' && '#A30002' || '#FFCC00' }}\",\n                        \"fallback\": \"test\",\n                        \"blocks\": [\n                            {\n                                \"type\": \"section\",\n                                \"fields\": [\n                                    {\n                                        \"type\": \"mrkdwn\",\n                                        \"text\": \"${{ github.event.workflow_run.event == 'pull_request' && format('*Pull Request:* {0} (`{1}`)\\n<{2}/pull/{3}|{4}>', github.repository, github.ref_name, github.event.repository.html_url, steps.get-pr-number.outputs.pull_request_number, github.event.workflow_run.display_title) || format('*Build:* {0} (`{1}`)\\n<{2}/commit/{3}|{4}>', github.repository, github.ref_name, github.event.repository.html_url, github.sha, github.event.workflow_run.display_title) }}\"\n                                    },\n                                    {\n                                        \"type\": \"mrkdwn\",\n                                        \"text\": \"*Status:*\\n`${{ github.event.workflow_run.conclusion }}`\"\n                                    }\n                                ]\n                            },\n                            {\n                                \"type\": \"section\",\n                                \"fields\": [\n                                    {\n                                        \"type\": \"mrkdwn\",\n                                        \"text\": \"*Author:*\\n`${{ github.actor }}`\"\n                                    },\n                                    {\n                                        \"type\": \"mrkdwn\",\n                                        \"text\": \"*Event:*\\n`${{ github.event.workflow_run.event }}`\"\n                                    }\n                                ]\n                            },\n                            {\n                                \"type\": \"divider\"\n                            },\n                            {\n                                \"type\": \"actions\",\n                                \"elements\": [\n                                    {\n                                        \"type\": \"button\",\n                                        \"text\": {\n                                            \"type\": \"plain_text\",\n                                            \"text\": \"Logs\"\n                                        },\n                                        \"url\": \"${{ github.event.workflow_run.html_url }}\"\n                                    },\n                                    {\n                                        \"type\": \"button\",\n                                        \"text\": {\n                                            \"type\": \"plain_text\",\n                                            \"text\": \"Commit\"\n                                        },\n                                        \"url\": \"${{ github.event.repository.html_url }}/commit/${{ github.sha }}\"\n                                    }\n                                ]\n                            }\n                        ]\n                    }\n                ]\n            }\n          token: ${{ secrets.SLACK_BOT_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "dist\nterraform-provider-talos\n_out\n\n### Terraform ###\n# Local .terraform directories\n**/.terraform/*\n\n# .tfstate files\n*.tfstate\n*.tfstate.*\n\n# Crash log files\ncrash.*.log\n\n# Exclude all .tfvars files, which are likely to contain sensitive data, such as\n# password, private keys, and other secrets. These should not be part of version\n# control as they are data points which are potentially sensitive and subject\n# to change depending on the environment.\n#*.tfvars\n#*.tfvars.json\n\n# Ignore override files as they are usually used to override resources locally and so\n# are not checked in\noverride.tf\noverride.tf.json\n*_override.tf\n*_override.tf.json\n\n# Include override files you do wish to add to version control using negated pattern\n# !example_override.tf\n\n# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan\n# example: *tfplan*\n\n# Ignore CLI configuration files\n.terraformrc\nterraform.rc\n"
  },
  {
    "path": ".golangci.yml",
    "content": "# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.\n#\n# Generated on 2025-07-11T15:25:51Z by kres 9b39fa4b-dirty.\n\nversion: \"2\"\n\n# options for analysis running\nrun:\n  modules-download-mode: readonly\n  issues-exit-code: 1\n  tests: true\n\n# output configuration options\noutput:\n  formats:\n    text:\n      path: stdout\n      print-issued-lines: true\n      print-linter-name: true\n  path-prefix: \"\"\n\n\nlinters:\n  default: all\n  disable:\n    - exhaustruct\n    - err113\n    - forbidigo\n    - funcorder\n    - funlen\n    - gochecknoglobals\n    - gochecknoinits\n    - godox\n    - gomoddirectives\n    - gosec\n    - inamedparam\n    - ireturn\n    - mnd\n    - nestif\n    - nonamedreturns\n    - paralleltest\n    - tagalign\n    - tagliatelle\n    - thelper\n    - varnamelen\n    - wrapcheck\n    - testifylint # complains about our assert recorder and has a number of false positives for assert.Greater(t, thing, 1)\n    - protogetter # complains about us using Value field on typed spec, instead of GetValue which has a different signature\n    - perfsprint # complains about us using fmt.Sprintf in non-performance critical code, updating just kres took too long\n    - musttag # seems to be broken - goes into imported libraries and reports issues there\n    - nolintlint # gives false positives - disable until https://github.com/golangci/golangci-lint/issues/3228 is resolved\n    - wsl # replaced by wsl_v5\n    - noinlineerr\n    - embeddedstructfieldcheck # fighting in many places with fieldalignment\n  # all available settings of specific linters\n  settings:\n    cyclop:\n      # the maximal code complexity to report\n      max-complexity: 20\n    dogsled:\n      max-blank-identifiers: 2\n    dupl:\n      threshold: 150\n    errcheck:\n      check-type-assertions: true\n      check-blank: true\n    exhaustive:\n      default-signifies-exhaustive: false\n    gocognit:\n      min-complexity: 30\n    nestif:\n      min-complexity: 5\n    goconst:\n      min-len: 3\n      min-occurrences: 3\n    gocritic:\n      disabled-checks: [ ]\n    gocyclo:\n      min-complexity: 20\n    godot:\n      scope: declarations\n    gomodguard: { }\n    govet:\n      enable-all: true\n    lll:\n      line-length: 200\n      tab-width: 4\n    misspell:\n      locale: US\n    nakedret:\n      max-func-lines: 30\n    prealloc:\n      simple: true\n      range-loops: true # Report preallocation suggestions on range loops, true by default\n      for-loops: false # Report preallocation suggestions on for loops, false by default\n    revive:\n      rules:\n        - name: var-naming # Complains about package names like \"common\"\n          disabled: true\n    rowserrcheck: { }\n    testpackage: { }\n    unparam:\n      check-exported: false\n    unused:\n      local-variables-are-used: false\n    whitespace:\n      multi-if: false   # Enforces newlines (or comments) after every multi-line if statement\n      multi-func: false # Enforces newlines (or comments) after every multi-line function signature\n    wsl:\n      strict-append: true\n      allow-assign-and-call: true\n      allow-multiline-assign: true\n      allow-trailing-comment: false\n      force-case-trailing-whitespace: 0\n      allow-separated-leading-comment: false\n      allow-cuddle-declarations: false\n      force-err-cuddling: false\n    depguard:\n      rules:\n        prevent_unmaintained_packages:\n          list-mode: lax # allow unless explicitly denied\n          files:\n            - $all\n          deny:\n            - pkg: io/ioutil\n              desc: \"replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil\"\n        test_kres_depguard_extra_rule_1:\n          deny:\n            - desc: Test rule 1\n              pkg: io/ioutil\n          files:\n            - test_1.go\n          list-mode: lax\n        test_kres_depguard_extra_rule_2:\n          deny:\n            - desc: Test rule 2\n              pkg: io/ioutil\n          files:\n            - test_2.go\n          list-mode: lax\n\n  exclusions:\n    generated: lax\n    paths:\n      - third_party$\n      - builtin$\n      - examples$\nissues:\n  max-issues-per-linter: 10\n  max-same-issues: 3\n  uniq-by-line: true\n  new: false\n\nseverity:\n  default: error\nformatters:\n  enable:\n    - gci\n    - gofmt\n    - gofumpt\n  settings:\n    gci:\n      sections:\n        - standard\n        - default\n        - localmodule\n    gofmt:\n      simplify: true\n    gofumpt:\n      extra-rules: false\n  exclusions:\n    generated: lax\n    paths:\n      - third_party$\n      - builtin$\n      - examples$\n"
  },
  {
    "path": ".goreleaser.yml",
    "content": "# Visit https://goreleaser.com for documentation on how to customize this\n# behavior.\nversion: 2\nbefore:\n  hooks:\n    # this is just an example and not a requirement for provider building/publishing\n    - go mod tidy\nbuilds:\n- env:\n    # goreleaser does not work with CGO, it could also complicate\n    # usage by users in CI/CD systems like Terraform Cloud where\n    # they are unable to install libraries.\n    - CGO_ENABLED=0\n  mod_timestamp: '{{ .CommitTimestamp }}'\n  flags:\n    - -trimpath\n  ldflags:\n    - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}'\n  goos:\n    - freebsd\n    - windows\n    - linux\n    - darwin\n  goarch:\n    - amd64\n    - '386'\n    - arm\n    - arm64\n  ignore:\n    - goos: darwin\n      goarch: '386'\n    - goos: windows\n      goarch: arm\n  binary: '{{ .ProjectName }}_v{{ .Version }}'\narchives:\n- formats: ['zip']\n  name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}'\nchecksum:\n  extra_files:\n    - glob: 'terraform-registry-manifest.json'\n      name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'\n  name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS'\n  algorithm: sha256\nsigns:\n  - artifacts: checksum\n    args:\n      # if you are using this in a GitHub action or some other automated pipeline, you\n      # need to pass the batch flag to indicate its not interactive.\n      - \"--batch\"\n      - \"--local-user\"\n      - \"{{ .Env.GPG_FINGERPRINT }}\" # set this environment variable for your signing key\n      - \"--output\"\n      - \"${signature}\"\n      - \"--detach-sign\"\n      - \"${artifact}\"\nrelease:\n  extra_files:\n    - glob: 'terraform-registry-manifest.json'\n      name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'\n    - glob: '_out/sbom.*.json'\n  # If you want to manually examine the release before its live, uncomment this line:\n  # draft: true\nchangelog:\n  disable: false\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"Debug Talos Terraform Provider\",\n            \"type\": \"go\",\n            \"request\": \"launch\",\n            \"mode\": \"debug\",\n            // this assumes your workspace is the root of the repo\n            \"program\": \"${workspaceFolder}\",\n            \"env\": {},\n            \"args\": [\n                \"-debug\",\n            ]\n        }\n    ]\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## [terraform-provider-talos 0.11.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.11.0) (2026-04-27)\n\nWelcome to the v0.11.0 release of terraform-provider-talos!\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### ephemeral resources\n\nNew ephemeral resources are added, please see docs.\n\n\n### Component Updates\n\nTalos sdk: v1.13.0\n\n\n### Contributors\n\n* Noel Georgi\n* Mickaël Canévet\n* Nikita COEUR\n* Dennis Witt\n* Nahue\n* purajit\n\n### Changes\n<details><summary>20 commits</summary>\n<p>\n\n* [`1c68732`](https://github.com/siderolabs/terraform-provider-talos/commit/1c68732ad71c09fbb0c425bafc26002348daa9ed) release(v0.11.0): prepare release\n* [`b5affe3`](https://github.com/siderolabs/terraform-provider-talos/commit/b5affe3b5259e9ca69492090a9a632203f34ad34) fix(docs): update talos_version description\n* [`ce4ede8`](https://github.com/siderolabs/terraform-provider-talos/commit/ce4ede85cc3d8a6cc5285c86f5a98b464666cc9c) fix: handle unknown-whole-list config_patches on machine_configuration_apply\n* [`000a3ec`](https://github.com/siderolabs/terraform-provider-talos/commit/000a3ec9946024587d4389e8c2a4463c6c53cf83) fix(ephemeral): detect machine_configuration_input_wo changes via hash\n* [`032a5ac`](https://github.com/siderolabs/terraform-provider-talos/commit/032a5ac6c75bbcd6e2d0f099bbbf500651d224a7) chore: bump deps\n* [`7b6a3e4`](https://github.com/siderolabs/terraform-provider-talos/commit/7b6a3e408457faa6c54b951791d6a8b3a7146d9c) fix: prevent empty resolved_apply_mode when reusing state\n* [`f427339`](https://github.com/siderolabs/terraform-provider-talos/commit/f4273395931496053d5e5c70b7c78b3f9c7bf652) release(v0.11.0-beta.2): prepare release\n* [`6ed1274`](https://github.com/siderolabs/terraform-provider-talos/commit/6ed1274cd7276b3f46465e2c7cc712ccb651c99f) feat: add sboms to release\n* [`4729352`](https://github.com/siderolabs/terraform-provider-talos/commit/4729352f7228f1f5454b0999798b5443ab15685e) feat(ephemeral): rewrite talos_cluster_kubeconfig to generate from machine_secrets\n* [`4992c4a`](https://github.com/siderolabs/terraform-provider-talos/commit/4992c4af6d23f3e0faf7fa9d58c5ccc46810ad2d) fix(ephemeral): rewrite talos_client_configuration to generate from machine_secrets\n* [`4c8def5`](https://github.com/siderolabs/terraform-provider-talos/commit/4c8def55f9ae57e5fefcaef83aab6e7a90557c1d) release(v0.11.0-beta.1): prepare release\n* [`01330a9`](https://github.com/siderolabs/terraform-provider-talos/commit/01330a9d19a2a27ed79fd78c6cd1623012f61d09) chore: update goreleaser schema\n* [`1585aed`](https://github.com/siderolabs/terraform-provider-talos/commit/1585aed51fcde7e158d45afa0be78f084693d396) fix: remove unsupported windows/arm build target for Go 1.25\n* [`d7bb719`](https://github.com/siderolabs/terraform-provider-talos/commit/d7bb7199c1a212431339d634b905c3b9b21d0a3f) release(v0.11.0-beta.0): prepare release\n* [`09f6c83`](https://github.com/siderolabs/terraform-provider-talos/commit/09f6c838e7430de02f62a1b968f425e0b2be4e0d) fix: restore correct skip_kubernetes_checks behavior\n* [`eaedcfd`](https://github.com/siderolabs/terraform-provider-talos/commit/eaedcfdda3e7e3193e3d23231673ef676f575ae5) chore: bump deps\n* [`f4d673f`](https://github.com/siderolabs/terraform-provider-talos/commit/f4d673f0851f25c5e15ef8ac9bd6fc12310ab2d5) feat: add ephemeral resources to prevent secrets from leaking to state\n* [`5f07e0f`](https://github.com/siderolabs/terraform-provider-talos/commit/5f07e0f6043687b2dc475aeb16d489968a2dd2c5) feat: add staged_if_needing_reboot apply mode for automatic reboot prevention\n* [`c8e3b87`](https://github.com/siderolabs/terraform-provider-talos/commit/c8e3b87002418699bf33a2b437f7ff59aa6c70ad) feat: add exact_filters attribute to talos_image_factory_extensions_versions\n* [`efe146e`](https://github.com/siderolabs/terraform-provider-talos/commit/efe146e512fb22dd1012849fce098256115961a4) fix: gracefully handle Unknown config_patches values\n</p>\n</details>\n\n### Changes since v0.11.0-beta.2\n<details><summary>6 commits</summary>\n<p>\n\n* [`1c68732`](https://github.com/siderolabs/terraform-provider-talos/commit/1c68732ad71c09fbb0c425bafc26002348daa9ed) release(v0.11.0): prepare release\n* [`b5affe3`](https://github.com/siderolabs/terraform-provider-talos/commit/b5affe3b5259e9ca69492090a9a632203f34ad34) fix(docs): update talos_version description\n* [`ce4ede8`](https://github.com/siderolabs/terraform-provider-talos/commit/ce4ede85cc3d8a6cc5285c86f5a98b464666cc9c) fix: handle unknown-whole-list config_patches on machine_configuration_apply\n* [`000a3ec`](https://github.com/siderolabs/terraform-provider-talos/commit/000a3ec9946024587d4389e8c2a4463c6c53cf83) fix(ephemeral): detect machine_configuration_input_wo changes via hash\n* [`032a5ac`](https://github.com/siderolabs/terraform-provider-talos/commit/032a5ac6c75bbcd6e2d0f099bbbf500651d224a7) chore: bump deps\n* [`7b6a3e4`](https://github.com/siderolabs/terraform-provider-talos/commit/7b6a3e408457faa6c54b951791d6a8b3a7146d9c) fix: prevent empty resolved_apply_mode when reusing state\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-framework**  v1.17.0 -> v1.19.0\n* **github.com/hashicorp/terraform-plugin-go**         v0.29.0 -> v0.31.0\n* **github.com/hashicorp/terraform-plugin-sdk/v2**     v2.38.1 -> v2.40.0\n* **github.com/hashicorp/terraform-plugin-testing**    v1.14.0 -> v1.15.0\n* **github.com/siderolabs/crypto**                     v0.6.4 -> v0.6.5\n* **github.com/siderolabs/image-factory**              v0.9.0 -> v1.1.0\n* **github.com/siderolabs/talos**                      v1.12.0 -> v1.13.0\n* **github.com/siderolabs/talos/pkg/machinery**        v1.12.0 -> v1.13.0\n* **go.yaml.in/yaml/v4**                               v4.0.0-rc.3 -> v4.0.0-rc.4\n* **golang.org/x/crypto**                              v0.50.0 **_new_**\n* **golang.org/x/mod**                                 v0.31.0 -> v0.35.0\n* **k8s.io/client-go**                                 v0.35.0 -> v0.35.4\n\nPrevious release can be found at [v0.10.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.10.1)\n\n## [terraform-provider-talos 0.11.0-beta.2](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.11.0-beta.2) (2026-03-31)\n\nWelcome to the v0.11.0-beta.2 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### ephemeral resources\n\nNew ephemeral resources are added, please see docs.\n\n\n### Component Updates\n\nTalos sdk: v1.13.0-beta.1\n\n\n### Contributors\n\n* Mickaël Canévet\n* Noel Georgi\n* Dennis Witt\n* Nikita COEUR\n* purajit\n\n### Changes\n<details><summary>13 commits</summary>\n<p>\n\n* [`6ed1274`](https://github.com/siderolabs/terraform-provider-talos/commit/6ed1274cd7276b3f46465e2c7cc712ccb651c99f) feat: add sboms to release\n* [`4729352`](https://github.com/siderolabs/terraform-provider-talos/commit/4729352f7228f1f5454b0999798b5443ab15685e) feat(ephemeral): rewrite talos_cluster_kubeconfig to generate from machine_secrets\n* [`4992c4a`](https://github.com/siderolabs/terraform-provider-talos/commit/4992c4af6d23f3e0faf7fa9d58c5ccc46810ad2d) fix(ephemeral): rewrite talos_client_configuration to generate from machine_secrets\n* [`4c8def5`](https://github.com/siderolabs/terraform-provider-talos/commit/4c8def55f9ae57e5fefcaef83aab6e7a90557c1d) release(v0.11.0-beta.1): prepare release\n* [`01330a9`](https://github.com/siderolabs/terraform-provider-talos/commit/01330a9d19a2a27ed79fd78c6cd1623012f61d09) chore: update goreleaser schema\n* [`1585aed`](https://github.com/siderolabs/terraform-provider-talos/commit/1585aed51fcde7e158d45afa0be78f084693d396) fix: remove unsupported windows/arm build target for Go 1.25\n* [`d7bb719`](https://github.com/siderolabs/terraform-provider-talos/commit/d7bb7199c1a212431339d634b905c3b9b21d0a3f) release(v0.11.0-beta.0): prepare release\n* [`09f6c83`](https://github.com/siderolabs/terraform-provider-talos/commit/09f6c838e7430de02f62a1b968f425e0b2be4e0d) fix: restore correct skip_kubernetes_checks behavior\n* [`eaedcfd`](https://github.com/siderolabs/terraform-provider-talos/commit/eaedcfdda3e7e3193e3d23231673ef676f575ae5) chore: bump deps\n* [`f4d673f`](https://github.com/siderolabs/terraform-provider-talos/commit/f4d673f0851f25c5e15ef8ac9bd6fc12310ab2d5) feat: add ephemeral resources to prevent secrets from leaking to state\n* [`5f07e0f`](https://github.com/siderolabs/terraform-provider-talos/commit/5f07e0f6043687b2dc475aeb16d489968a2dd2c5) feat: add staged_if_needing_reboot apply mode for automatic reboot prevention\n* [`c8e3b87`](https://github.com/siderolabs/terraform-provider-talos/commit/c8e3b87002418699bf33a2b437f7ff59aa6c70ad) feat: add exact_filters attribute to talos_image_factory_extensions_versions\n* [`efe146e`](https://github.com/siderolabs/terraform-provider-talos/commit/efe146e512fb22dd1012849fce098256115961a4) fix: gracefully handle Unknown config_patches values\n</p>\n</details>\n\n### Changes since v0.11.0-beta.1\n<details><summary>3 commits</summary>\n<p>\n\n* [`6ed1274`](https://github.com/siderolabs/terraform-provider-talos/commit/6ed1274cd7276b3f46465e2c7cc712ccb651c99f) feat: add sboms to release\n* [`4729352`](https://github.com/siderolabs/terraform-provider-talos/commit/4729352f7228f1f5454b0999798b5443ab15685e) feat(ephemeral): rewrite talos_cluster_kubeconfig to generate from machine_secrets\n* [`4992c4a`](https://github.com/siderolabs/terraform-provider-talos/commit/4992c4af6d23f3e0faf7fa9d58c5ccc46810ad2d) fix(ephemeral): rewrite talos_client_configuration to generate from machine_secrets\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-framework**  v1.17.0 -> v1.19.0\n* **github.com/hashicorp/terraform-plugin-go**         v0.29.0 -> v0.31.0\n* **github.com/hashicorp/terraform-plugin-sdk/v2**     v2.38.1 -> v2.40.0\n* **github.com/hashicorp/terraform-plugin-testing**    v1.14.0 -> v1.15.0\n* **github.com/siderolabs/image-factory**              v0.9.0 -> v1.0.3\n* **github.com/siderolabs/talos**                      v1.12.0 -> v1.13.0-beta.1\n* **github.com/siderolabs/talos/pkg/machinery**        v1.12.0 -> v1.13.0-beta.1\n* **go.yaml.in/yaml/v4**                               v4.0.0-rc.3 -> v4.0.0-rc.4\n* **golang.org/x/crypto**                              v0.49.0 **_new_**\n* **golang.org/x/mod**                                 v0.31.0 -> v0.34.0\n* **k8s.io/client-go**                                 v0.35.0 -> v0.35.3\n\nPrevious release can be found at [v0.10.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.10.1)\n\n## [terraform-provider-talos 0.11.0-beta.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.11.0-beta.1) (2026-02-27)\n\nWelcome to the v0.11.0-beta.1 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### ephemeral resources\n\nNew ephemeral resources are added, please see docs.\n\n\n### Component Updates\n\nTalos sdk: v1.13.0-alpha.1\n\n\n### Contributors\n\n* Mickaël Canévet\n* Noel Georgi\n* Dennis Witt\n* Nikita COEUR\n* purajit\n\n### Changes\n<details><summary>9 commits</summary>\n<p>\n\n* [`01330a9`](https://github.com/siderolabs/terraform-provider-talos/commit/01330a9d19a2a27ed79fd78c6cd1623012f61d09) chore: update goreleaser schema\n* [`1585aed`](https://github.com/siderolabs/terraform-provider-talos/commit/1585aed51fcde7e158d45afa0be78f084693d396) fix: remove unsupported windows/arm build target for Go 1.25\n* [`d7bb719`](https://github.com/siderolabs/terraform-provider-talos/commit/d7bb7199c1a212431339d634b905c3b9b21d0a3f) release(v0.11.0-beta.0): prepare release\n* [`09f6c83`](https://github.com/siderolabs/terraform-provider-talos/commit/09f6c838e7430de02f62a1b968f425e0b2be4e0d) fix: restore correct skip_kubernetes_checks behavior\n* [`eaedcfd`](https://github.com/siderolabs/terraform-provider-talos/commit/eaedcfdda3e7e3193e3d23231673ef676f575ae5) chore: bump deps\n* [`f4d673f`](https://github.com/siderolabs/terraform-provider-talos/commit/f4d673f0851f25c5e15ef8ac9bd6fc12310ab2d5) feat: add ephemeral resources to prevent secrets from leaking to state\n* [`5f07e0f`](https://github.com/siderolabs/terraform-provider-talos/commit/5f07e0f6043687b2dc475aeb16d489968a2dd2c5) feat: add staged_if_needing_reboot apply mode for automatic reboot prevention\n* [`c8e3b87`](https://github.com/siderolabs/terraform-provider-talos/commit/c8e3b87002418699bf33a2b437f7ff59aa6c70ad) feat: add exact_filters attribute to talos_image_factory_extensions_versions\n* [`efe146e`](https://github.com/siderolabs/terraform-provider-talos/commit/efe146e512fb22dd1012849fce098256115961a4) fix: gracefully handle Unknown config_patches values\n</p>\n</details>\n\n### Changes since v0.11.0-beta.0\n<details><summary>2 commits</summary>\n<p>\n\n* [`01330a9`](https://github.com/siderolabs/terraform-provider-talos/commit/01330a9d19a2a27ed79fd78c6cd1623012f61d09) chore: update goreleaser schema\n* [`1585aed`](https://github.com/siderolabs/terraform-provider-talos/commit/1585aed51fcde7e158d45afa0be78f084693d396) fix: remove unsupported windows/arm build target for Go 1.25\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-go**      v0.29.0 -> v0.30.0\n* **github.com/hashicorp/terraform-plugin-sdk/v2**  v2.38.1 -> v2.38.2\n* **github.com/siderolabs/image-factory**           v0.9.0 -> v1.0.3\n* **github.com/siderolabs/talos**                   v1.12.0 -> v1.13.0-alpha.2\n* **github.com/siderolabs/talos/pkg/machinery**     v1.12.0 -> v1.13.0-alpha.2\n* **go.yaml.in/yaml/v4**                            v4.0.0-rc.3 -> v4.0.0-rc.4\n* **golang.org/x/mod**                              v0.31.0 -> v0.33.0\n* **k8s.io/client-go**                              v0.35.0 -> v0.35.1\n\nPrevious release can be found at [v0.10.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.10.1)\n\n## [terraform-provider-talos 0.11.0-beta.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.11.0-beta.0) (2026-02-26)\n\nWelcome to the v0.11.0-beta.0 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### ephemeral resources\n\nNew ephemeral resources are added, please see docs.\n\n\n### Component Updates\n\nTalos sdk: v1.13.0-alpha.1\n\n\n### Contributors\n\n* Mickaël Canévet\n* Dennis Witt\n* Nikita COEUR\n* Noel Georgi\n* purajit\n\n### Changes\n<details><summary>6 commits</summary>\n<p>\n\n* [`09f6c83`](https://github.com/siderolabs/terraform-provider-talos/commit/09f6c838e7430de02f62a1b968f425e0b2be4e0d) fix: restore correct skip_kubernetes_checks behavior\n* [`eaedcfd`](https://github.com/siderolabs/terraform-provider-talos/commit/eaedcfdda3e7e3193e3d23231673ef676f575ae5) chore: bump deps\n* [`f4d673f`](https://github.com/siderolabs/terraform-provider-talos/commit/f4d673f0851f25c5e15ef8ac9bd6fc12310ab2d5) feat: add ephemeral resources to prevent secrets from leaking to state\n* [`5f07e0f`](https://github.com/siderolabs/terraform-provider-talos/commit/5f07e0f6043687b2dc475aeb16d489968a2dd2c5) feat: add staged_if_needing_reboot apply mode for automatic reboot prevention\n* [`c8e3b87`](https://github.com/siderolabs/terraform-provider-talos/commit/c8e3b87002418699bf33a2b437f7ff59aa6c70ad) feat: add exact_filters attribute to talos_image_factory_extensions_versions\n* [`efe146e`](https://github.com/siderolabs/terraform-provider-talos/commit/efe146e512fb22dd1012849fce098256115961a4) fix: gracefully handle Unknown config_patches values\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-go**      v0.29.0 -> v0.30.0\n* **github.com/hashicorp/terraform-plugin-sdk/v2**  v2.38.1 -> v2.38.2\n* **github.com/siderolabs/image-factory**           v0.9.0 -> v1.0.3\n* **github.com/siderolabs/talos**                   v1.12.0 -> v1.13.0-alpha.2\n* **github.com/siderolabs/talos/pkg/machinery**     v1.12.0 -> v1.13.0-alpha.2\n* **go.yaml.in/yaml/v4**                            v4.0.0-rc.3 -> v4.0.0-rc.4\n* **golang.org/x/mod**                              v0.31.0 -> v0.33.0\n* **k8s.io/client-go**                              v0.35.0 -> v0.35.1\n\nPrevious release can be found at [v0.10.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.10.1)\n\n## [terraform-provider-talos 0.10.0-beta.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.10.0-beta.0) (2025-11-28)\n\nWelcome to the v0.10.0-beta.0 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### config patches\n\nJSON6502 patches are no longer supported, use strategic patches instead.\n\n\n### Component Updates\n\nTalos sdk: v1.12.0-beta.0\n\n\n### Contributors\n\n* Noel Georgi\n\n### Changes\n<details><summary>1 commit</summary>\n<p>\n\n* [`11063bc`](https://github.com/siderolabs/terraform-provider-talos/commit/11063bc25f97c7abb8ae9ceb099bbc523c8655b8) chore: bump deps\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-docs**                  v0.22.0 -> v0.24.0\n* **github.com/hashicorp/terraform-plugin-framework**             v1.15.1 -> v1.16.1\n* **github.com/hashicorp/terraform-plugin-framework-timeouts**    v0.5.0 -> v0.7.0\n* **github.com/hashicorp/terraform-plugin-framework-validators**  v0.18.0 -> v0.19.0\n* **github.com/hashicorp/terraform-plugin-go**                    v0.28.0 -> v0.29.0\n* **github.com/hashicorp/terraform-plugin-log**                   v0.9.0 -> v0.10.0\n* **github.com/hashicorp/terraform-plugin-sdk/v2**                v2.37.0 -> v2.38.1\n* **github.com/siderolabs/crypto**                                v0.6.3 -> v0.6.4\n* **github.com/siderolabs/gen**                                   v0.8.5 -> v0.8.6\n* **github.com/siderolabs/image-factory**                         v0.8.3 -> v0.9.0\n* **github.com/siderolabs/talos**                                 v1.11.0 -> v1.12.0-beta.0\n* **github.com/siderolabs/talos/pkg/machinery**                   v1.11.0 -> v1.12.0-beta.0\n* **go.yaml.in/yaml/v4**                                          v4.0.0-rc.3 **_new_**\n* **golang.org/x/mod**                                            v0.27.0 -> v0.30.0\n* **k8s.io/client-go**                                            v0.34.0 -> v0.35.0-alpha.3\n\nPrevious release can be found at [v0.9.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.9.0)\n\n## [terraform-provider-talos 0.9.0-alpha.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.9.0-alpha.0) (2025-05-19)\n\nWelcome to the v0.9.0-alpha.0 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### talos_machine_disks Data Source\n\nThe `talos_machine_disks` data source has been updated to use the better CEL expression language.\nThe resource attributes and selector have been updated to use the new syntax.\nThe user would need to update the data source in their configuration to use the new syntax.\nThe expression syntax is documented in the [CEL documentation](https://www.talos.dev/latest/talos-guides/configuration/disk-management/#disk-selector).\n\nThis also brings in consistency with how disks are reported in Talos.\n\n\n### Component Updates\n\nTalos sdk: v1.11.0-alpha.0\n\n\n### Contributors\n\n* Noel Georgi\n* Halvdan Hoem Grelland\n* obvionaoe\n\n### Changes\n<details><summary>7 commits</summary>\n<p>\n\n* [`4016c0c`](https://github.com/siderolabs/terraform-provider-talos/commit/4016c0cc890585c6343829b99d23a22c4fb4bb42) fix: secureboot installer urls for non-metal platform\n* [`34f3f1e`](https://github.com/siderolabs/terraform-provider-talos/commit/34f3f1e74a5e7b65cc82a5c46b5929fbde530790) chore: simplify disk selector code\n* [`93070aa`](https://github.com/siderolabs/terraform-provider-talos/commit/93070aaa166aa2ba81a3322bac2de4b9ef927319) feat: use CEL expression filters for `talos_machine_disks`\n* [`f70e10e`](https://github.com/siderolabs/terraform-provider-talos/commit/f70e10e97d81a1b211c7d09dd3b04156ece70d1a) fix: allow talos_version to be used without a `v` prefix\n* [`fa8002d`](https://github.com/siderolabs/terraform-provider-talos/commit/fa8002d47d35c558ae810e50f6ed0beaa759454a) chore: bump deps\n* [`e76002d`](https://github.com/siderolabs/terraform-provider-talos/commit/e76002d6bf47b39d474cc5bc01c0b919afb20046) fix: factory installer urls\n* [`44eec1c`](https://github.com/siderolabs/terraform-provider-talos/commit/44eec1cc87eeae3d5eaaf45ea742807eea32367a) fix: image factory examples and docs\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-framework-validators**  v0.17.0 -> v0.18.0\n* **github.com/siderolabs/gen**                                   v0.8.0 -> v0.8.1\n* **github.com/siderolabs/image-factory**                         v0.6.9 -> v0.7.0\n* **github.com/siderolabs/talos**                                 v1.10.0 -> v1.11.0-alpha.0\n* **github.com/siderolabs/talos/pkg/machinery**                   v1.10.0 -> v1.11.0-alpha.0\n\nPrevious release can be found at [v0.8.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.8.1)\n\n## [terraform-provider-talos 0.8.0-alpha.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.8.0-alpha.0) (2025-04-18)\n\nWelcome to the v0.8.0-alpha.0 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Component Updates\n\nTalos sdk: v1.10.0-beta.0\n\n\n### Contributors\n\n* Noel Georgi\n* Andrey Smirnov\n* Matt Willsher\n\n### Changes\n<details><summary>5 commits</summary>\n<p>\n\n* [`2cfcf88`](https://github.com/siderolabs/terraform-provider-talos/commit/2cfcf8802e61550ad7570aa8cbd44439700fd677) chore: bump deps\n* [`46ab81c`](https://github.com/siderolabs/terraform-provider-talos/commit/46ab81ca8b799e5390cf398a4a65210d2425a41e) fix: drop talos<->k8s compatibility check\n* [`69596f1`](https://github.com/siderolabs/terraform-provider-talos/commit/69596f1e4b74a1d0f95e663315724d9e8150b5b0) fix: skip if aggregator certs are nil\n* [`d3214dc`](https://github.com/siderolabs/terraform-provider-talos/commit/d3214dc15659de2906c1aaf2912e77a90dfaca7b) refactor: pull platform metadata from Talos machinery\n* [`5c0ff77`](https://github.com/siderolabs/terraform-provider-talos/commit/5c0ff772a72339827bbd63d3fe59c52fb73148de) feat: add secure boot support to non-metal image factory urls\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-docs**                  v0.20.1 -> v0.21.0\n* **github.com/hashicorp/terraform-plugin-framework**             v1.13.0 -> v1.14.1\n* **github.com/hashicorp/terraform-plugin-framework-timeouts**    v0.4.1 -> v0.5.0\n* **github.com/hashicorp/terraform-plugin-framework-validators**  v0.16.0 -> v0.17.0\n* **github.com/hashicorp/terraform-plugin-go**                    v0.25.0 -> v0.26.0\n* **github.com/hashicorp/terraform-plugin-sdk/v2**                v2.35.0 -> v2.36.1\n* **github.com/hashicorp/terraform-plugin-testing**               v1.11.0 -> v1.12.0\n* **github.com/siderolabs/image-factory**                         v0.6.4 -> v0.6.8\n* **github.com/siderolabs/talos**                                 v1.9.2 -> v1.10.0-beta.0\n* **github.com/siderolabs/talos/pkg/machinery**                   v1.9.2 -> v1.10.0-beta.0\n* **golang.org/x/mod**                                            v0.22.0 -> v0.24.0\n* **k8s.io/client-go**                                            v0.32.0 -> v0.33.0-rc.0\n\nPrevious release can be found at [v0.7.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.7.1)\n\n## [terraform-provider-talos 0.8.0-alpha.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.8.0-alpha.0) (2025-04-18)\n\nWelcome to the v0.8.0-alpha.0 release of terraform-provider-talos!\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Component Updates\n\nTalos sdk: v1.10.0-beta.0\n\n\n### Contributors\n\n* Noel Georgi\n* Andrey Smirnov\n* Matt Willsher\n\n### Changes\n<details><summary>5 commits</summary>\n<p>\n\n* [`2cfcf88`](https://github.com/siderolabs/terraform-provider-talos/commit/2cfcf8802e61550ad7570aa8cbd44439700fd677) chore: bump deps\n* [`46ab81c`](https://github.com/siderolabs/terraform-provider-talos/commit/46ab81ca8b799e5390cf398a4a65210d2425a41e) fix: drop talos<->k8s compatibility check\n* [`69596f1`](https://github.com/siderolabs/terraform-provider-talos/commit/69596f1e4b74a1d0f95e663315724d9e8150b5b0) fix: skip if aggregator certs are nil\n* [`d3214dc`](https://github.com/siderolabs/terraform-provider-talos/commit/d3214dc15659de2906c1aaf2912e77a90dfaca7b) refactor: pull platform metadata from Talos machinery\n* [`5c0ff77`](https://github.com/siderolabs/terraform-provider-talos/commit/5c0ff772a72339827bbd63d3fe59c52fb73148de) feat: add secure boot support to non-metal image factory urls\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-docs**                  v0.20.1 -> v0.21.0\n* **github.com/hashicorp/terraform-plugin-framework**             v1.13.0 -> v1.14.1\n* **github.com/hashicorp/terraform-plugin-framework-timeouts**    v0.4.1 -> v0.5.0\n* **github.com/hashicorp/terraform-plugin-framework-validators**  v0.16.0 -> v0.17.0\n* **github.com/hashicorp/terraform-plugin-go**                    v0.25.0 -> v0.26.0\n* **github.com/hashicorp/terraform-plugin-sdk/v2**                v2.35.0 -> v2.36.1\n* **github.com/hashicorp/terraform-plugin-testing**               v1.11.0 -> v1.12.0\n* **github.com/siderolabs/image-factory**                         v0.6.4 -> v0.6.8\n* **github.com/siderolabs/talos**                                 v1.9.2 -> v1.10.0-beta.0\n* **github.com/siderolabs/talos/pkg/machinery**                   v1.9.2 -> v1.10.0-beta.0\n* **golang.org/x/mod**                                            v0.22.0 -> v0.24.0\n* **k8s.io/client-go**                                            v0.32.0 -> v0.33.0-rc.0\n\nPrevious release can be found at [v0.7.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.7.1)\n\n## [terraform-provider-talos 0.7.0-alpha.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.7.0-alpha.0) (2024-10-21)\n\nWelcome to the v0.7.0-alpha.0 release of terraform-provider-talos!\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Component Updates\n\nTalos sdk: v1.9.0-alpha.0\n\n\n### Contributors\n\n* Noel Georgi\n\n### Changes\n<details><summary>1 commit</summary>\n<p>\n\n* [`beb5e2b`](https://github.com/siderolabs/terraform-provider-talos/commit/beb5e2b38466116da1d212dea33f5d7926655442) chore: bump deps\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-framework-validators**  v0.13.0 -> v0.14.0\n* **github.com/siderolabs/talos**                                 v1.8.1 -> v1.9.0-alpha.0\n* **github.com/siderolabs/talos/pkg/machinery**                   v1.8.1 -> v1.9.0-alpha.0\n\nPrevious release can be found at [v0.6.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.6.1)\n\n## [terraform-provider-talos 0.6.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.6.1) (2024-10-18)\n\nWelcome to the v0.6.1 release of terraform-provider-talos!\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Talos Cluster Kubeconfig\n\nThe `talos_cluster_kubeconfig` resource now supports confiuring the certificate renewal check time.\n\n\n### Component Updates\n\nTalos sdk: v1.8.1\n\n\n### Contributors\n\n* Noel Georgi\n\n### Changes\n<details><summary>3 commits</summary>\n<p>\n\n* [`daddfb7`](https://github.com/siderolabs/terraform-provider-talos/commit/daddfb76cec78135ad62e8e46f4d965eb6eed52a) feat: configurable cert refresh time for kubeconfig\n* [`96c9a85`](https://github.com/siderolabs/terraform-provider-talos/commit/96c9a857f9df8a28b7f32f1d0cf948a74a8acfcb) fix: resourceplanmodifiers for kubeconfig resource\n* [`800573b`](https://github.com/siderolabs/terraform-provider-talos/commit/800573b841c901f562b8b2b151e58d86516944d0) fix: disks wipe on destroy\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-framework**  v1.11.0 -> v1.12.0\n* **github.com/hashicorp/terraform-plugin-go**         v0.23.0 -> v0.24.0\n* **github.com/siderolabs/crypto**                     v0.4.4 -> v0.5.0\n* **github.com/siderolabs/go-blockdevice**             v0.4.7 -> v0.4.8\n* **github.com/siderolabs/talos**                      v1.8.0 -> v1.8.1\n* **github.com/siderolabs/talos/pkg/machinery**        v1.8.0 -> v1.8.1\n\nPrevious release can be found at [v0.6.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.6.0)\n\n\n## [terraform-provider-talos 0.6.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.6.0) (2024-09-23)\n\nWelcome to the v0.6.0 release of terraform-provider-talos!\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Image Factory\n\nSupport for querying info from Image Factory and registering schematics is now supported via new Terraform resources.\n\n\n### Talos Cluster Health\n\n`talos_cluster_health` data source now has a way to skip running the Kubernetes components health check by setting `skip_kubernetes_checks` to `true`.\n\n\n### Talos Cluster Kubeconfig\n\n`talos_cluster_kubeconfig` data source is now deprecated and will be removed in the next minor release.\nUse `talos_cluster_kubeconfig` resource instead.\nThe `talos_cluster_kubeconfig` resource will regenerate kubernetes client config when the time to expiry is less than a month.\n\n\n### Talos Machine Configuration Data Source\n\n`talos_machine_configuration` data source now defaults to generating config with documentation and examples disabled.\n\nTo restore the previous behavior, set `docs` and `examples` attributes to `true`.\n\n\n### Talos Machine Configuration Apply\n\n`talos_machine_configuration_apply` resource now optionally supports resetting the machine back to maintenance mode.\n\n\n### Talos Machine Secrets\n\n`talos_machine_secrets` resource now regenerates client config when the time to expiry is less than a month.\n\n\n### Component Updates\n\nTalos sdk: v1.8.0-alpha.1\n\n\n### Contributors\n\n* Noel Georgi\n* Bruno Bigras\n* Hippie Hacker\n\n### Changes\n<details><summary>20 commits</summary>\n<p>\n\n* [`758df67`](https://github.com/siderolabs/terraform-provider-talos/commit/758df676873a53d0833b79f74f74c1d0cfbb1f12) docs: machine_configuration fix typo\n* [`4e01809`](https://github.com/siderolabs/terraform-provider-talos/commit/4e0180983319098412faab94b18a97ca43cae192) release(v0.6.0-beta.0): prepare release\n* [`8dcab7b`](https://github.com/siderolabs/terraform-provider-talos/commit/8dcab7bc766edf0b386c1a061a71f3541c75b56d) chore: bump deps\n* [`3b59c4a`](https://github.com/siderolabs/terraform-provider-talos/commit/3b59c4a34fc3b1b824bf104981ac70ebc5e6e722) release(v0.6.0-alpha.2): prepare release\n* [`858f7f3`](https://github.com/siderolabs/terraform-provider-talos/commit/858f7f3de9368604b8f18125420d6888606b21be) chore: bump deps\n* [`7af49b3`](https://github.com/siderolabs/terraform-provider-talos/commit/7af49b315e4b37b7a165c6ef5d5dc2830dc00a6f) chore: better health checks from talos sdk\n* [`063b7ae`](https://github.com/siderolabs/terraform-provider-talos/commit/063b7aeb9dc69782ec7cf541433f7b1eb92e4197) chore: default talos_machine_configuration docs and examples to false\n* [`80c5534`](https://github.com/siderolabs/terraform-provider-talos/commit/80c5534fbd876506201f21b50c950ce053402a55) chore: support filtering stable version\n* [`b9c7f5f`](https://github.com/siderolabs/terraform-provider-talos/commit/b9c7f5f8aedaca50a4e694e022cae456cd44d065) release(v0.6.0-alpha.1): prepare release\n* [`92fcb70`](https://github.com/siderolabs/terraform-provider-talos/commit/92fcb70cd9c1d6cfb5bd3ea159e56fa493fe62db) feat: add `talos_image_factory_url` data source\n* [`ffc8102`](https://github.com/siderolabs/terraform-provider-talos/commit/ffc8102dd7f7b0929dc54fa1f50afd9b2cfda6be) feat: add factory support\n* [`d6c2a0b`](https://github.com/siderolabs/terraform-provider-talos/commit/d6c2a0bc939de41252d97f09b8e9dfcff3377450) chore: fix goreleaser config\n* [`dcdcee6`](https://github.com/siderolabs/terraform-provider-talos/commit/dcdcee62f8d9429cc0416dfdb92dfc27391da0ee) release(v0.6.0-alpha.0): prepare release\n* [`d962913`](https://github.com/siderolabs/terraform-provider-talos/commit/d9629133c03ef09d5a6136b0e6cc1624a7ef4c28) chore: reset options for `machine_configuration_apply` resource\n* [`f26a591`](https://github.com/siderolabs/terraform-provider-talos/commit/f26a5911bdd243fd384a353de1c0140de256211c) chore: data source -> resource `talos_cluster_kubeconfig`\n* [`78fd0d3`](https://github.com/siderolabs/terraform-provider-talos/commit/78fd0d369ff401fbd795609cbbc2275f7d108bb0) chore: ignore version prefix for `talos_version`\n* [`11ae330`](https://github.com/siderolabs/terraform-provider-talos/commit/11ae33002bee7a3e319bc7f9ea7555ca3ebaa120) feat: support skipping k8s health checks\n* [`0fe1a6f`](https://github.com/siderolabs/terraform-provider-talos/commit/0fe1a6fe8d4440f72d7c553cf961b0de7267404b) docs: update description of `talos_cluster_health`\n* [`f6f1811`](https://github.com/siderolabs/terraform-provider-talos/commit/f6f1811e90c9eef91f562f1f8b15f78e984315a0) feat: regenerate talosconfig\n* [`501c78e`](https://github.com/siderolabs/terraform-provider-talos/commit/501c78eb7403012c90229bfc24399d0e1603289b) chore: bump deps\n</p>\n</details>\n\n### Changes since v0.6.0-beta.0\n<details><summary>1 commit</summary>\n<p>\n\n* [`758df67`](https://github.com/siderolabs/terraform-provider-talos/commit/758df676873a53d0833b79f74f74c1d0cfbb1f12) docs: machine_configuration fix typo\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/blang/semver/v4**                                  v4.0.0 **_new_**\n* **github.com/hashicorp/terraform-plugin-docs**                  v0.19.0 -> v0.19.4\n* **github.com/hashicorp/terraform-plugin-framework**             v1.7.0 -> v1.11.0\n* **github.com/hashicorp/terraform-plugin-framework-validators**  v0.12.0 -> v0.13.0\n* **github.com/hashicorp/terraform-plugin-go**                    v0.22.1 -> v0.23.0\n* **github.com/hashicorp/terraform-plugin-log**                   v0.9.0 **_new_**\n* **github.com/hashicorp/terraform-plugin-sdk/v2**                v2.33.0 -> v2.34.0\n* **github.com/hashicorp/terraform-plugin-testing**               v1.7.0 -> v1.10.0\n* **github.com/siderolabs/gen**                                   v0.4.8 -> v0.5.0\n* **github.com/siderolabs/image-factory**                         v0.5.0 **_new_**\n* **github.com/siderolabs/talos**                                 v1.8.0-beta.0 **_new_**\n* **github.com/siderolabs/talos/pkg/machinery**                   v1.7.0 -> v1.8.0-beta.0\n* **golang.org/x/mod**                                            v0.17.0 -> v0.21.0\n* **k8s.io/client-go**                                            v0.29.3 -> v0.31.0\n\nPrevious release can be found at [v0.5.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.5.0)\n\n## [terraform-provider-talos 0.6.0-beta.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.6.0-beta.0) (2024-09-10)\n\nWelcome to the v0.6.0-beta.0 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Image Factory\n\nSupport for querying info from Image Factory and registering schematics is now supported via new Terraform resources.\n\n\n### Talos Cluster Health\n\n`talos_cluster_health` data source now has a way to skip running the Kubernetes components health check by setting `skip_kubernetes_checks` to `true`.\n\n\n### Talos Cluster Kubeconfig\n\n`talos_cluster_kubeconfig` data source is now deprecated and will be removed in the next minor release.\nUse `talos_cluster_kubeconfig` resource instead.\nThe `talos_cluster_kubeconfig` resource will regenerate kubernetes client config when the time to expiry is less than a month.\n\n\n### Talos Machine Configuration Data Source\n\n`talos_machine_configuration` data source now defaults to generating config with documentation and examples disabled.\n\nTo restore the previous behavior, set `docs` and `examples` attributes to `true`.\n\n\n### Talos Machine Configuration Apply\n\n`talos_machine_configuration_apply` resource now optionally supports resetting the machine back to maintenance mode.\n\n\n### Talos Machine Secrets\n\n`talos_machine_secrets` resource now regenerates client config when the time to expiry is less than a month.\n\n\n### Component Updates\n\nTalos sdk: v1.8.0-alpha.1\n\n\n### Contributors\n\n* Noel Georgi\n* Hippie Hacker\n\n### Changes\n<details><summary>18 commits</summary>\n<p>\n\n* [`8dcab7b`](https://github.com/siderolabs/terraform-provider-talos/commit/8dcab7bc766edf0b386c1a061a71f3541c75b56d) chore: bump deps\n* [`3b59c4a`](https://github.com/siderolabs/terraform-provider-talos/commit/3b59c4a34fc3b1b824bf104981ac70ebc5e6e722) release(v0.6.0-alpha.2): prepare release\n* [`858f7f3`](https://github.com/siderolabs/terraform-provider-talos/commit/858f7f3de9368604b8f18125420d6888606b21be) chore: bump deps\n* [`7af49b3`](https://github.com/siderolabs/terraform-provider-talos/commit/7af49b315e4b37b7a165c6ef5d5dc2830dc00a6f) chore: better health checks from talos sdk\n* [`063b7ae`](https://github.com/siderolabs/terraform-provider-talos/commit/063b7aeb9dc69782ec7cf541433f7b1eb92e4197) chore: default talos_machine_configuration docs and examples to false\n* [`80c5534`](https://github.com/siderolabs/terraform-provider-talos/commit/80c5534fbd876506201f21b50c950ce053402a55) chore: support filtering stable version\n* [`b9c7f5f`](https://github.com/siderolabs/terraform-provider-talos/commit/b9c7f5f8aedaca50a4e694e022cae456cd44d065) release(v0.6.0-alpha.1): prepare release\n* [`92fcb70`](https://github.com/siderolabs/terraform-provider-talos/commit/92fcb70cd9c1d6cfb5bd3ea159e56fa493fe62db) feat: add `talos_image_factory_url` data source\n* [`ffc8102`](https://github.com/siderolabs/terraform-provider-talos/commit/ffc8102dd7f7b0929dc54fa1f50afd9b2cfda6be) feat: add factory support\n* [`d6c2a0b`](https://github.com/siderolabs/terraform-provider-talos/commit/d6c2a0bc939de41252d97f09b8e9dfcff3377450) chore: fix goreleaser config\n* [`dcdcee6`](https://github.com/siderolabs/terraform-provider-talos/commit/dcdcee62f8d9429cc0416dfdb92dfc27391da0ee) release(v0.6.0-alpha.0): prepare release\n* [`d962913`](https://github.com/siderolabs/terraform-provider-talos/commit/d9629133c03ef09d5a6136b0e6cc1624a7ef4c28) chore: reset options for `machine_configuration_apply` resource\n* [`f26a591`](https://github.com/siderolabs/terraform-provider-talos/commit/f26a5911bdd243fd384a353de1c0140de256211c) chore: data source -> resource `talos_cluster_kubeconfig`\n* [`78fd0d3`](https://github.com/siderolabs/terraform-provider-talos/commit/78fd0d369ff401fbd795609cbbc2275f7d108bb0) chore: ignore version prefix for `talos_version`\n* [`11ae330`](https://github.com/siderolabs/terraform-provider-talos/commit/11ae33002bee7a3e319bc7f9ea7555ca3ebaa120) feat: support skipping k8s health checks\n* [`0fe1a6f`](https://github.com/siderolabs/terraform-provider-talos/commit/0fe1a6fe8d4440f72d7c553cf961b0de7267404b) docs: update description of `talos_cluster_health`\n* [`f6f1811`](https://github.com/siderolabs/terraform-provider-talos/commit/f6f1811e90c9eef91f562f1f8b15f78e984315a0) feat: regenerate talosconfig\n* [`501c78e`](https://github.com/siderolabs/terraform-provider-talos/commit/501c78eb7403012c90229bfc24399d0e1603289b) chore: bump deps\n</p>\n</details>\n\n### Changes since v0.6.0-alpha.2\n<details><summary>1 commit</summary>\n<p>\n\n* [`8dcab7b`](https://github.com/siderolabs/terraform-provider-talos/commit/8dcab7bc766edf0b386c1a061a71f3541c75b56d) chore: bump deps\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/blang/semver/v4**                                  v4.0.0 **_new_**\n* **github.com/hashicorp/terraform-plugin-docs**                  v0.19.0 -> v0.19.4\n* **github.com/hashicorp/terraform-plugin-framework**             v1.7.0 -> v1.11.0\n* **github.com/hashicorp/terraform-plugin-framework-validators**  v0.12.0 -> v0.13.0\n* **github.com/hashicorp/terraform-plugin-go**                    v0.22.1 -> v0.23.0\n* **github.com/hashicorp/terraform-plugin-log**                   v0.9.0 **_new_**\n* **github.com/hashicorp/terraform-plugin-sdk/v2**                v2.33.0 -> v2.34.0\n* **github.com/hashicorp/terraform-plugin-testing**               v1.7.0 -> v1.10.0\n* **github.com/siderolabs/gen**                                   v0.4.8 -> v0.5.0\n* **github.com/siderolabs/image-factory**                         v0.5.0 **_new_**\n* **github.com/siderolabs/talos**                                 v1.8.0-beta.0 **_new_**\n* **github.com/siderolabs/talos/pkg/machinery**                   v1.7.0 -> v1.8.0-beta.0\n* **golang.org/x/mod**                                            v0.17.0 -> v0.21.0\n* **k8s.io/client-go**                                            v0.29.3 -> v0.31.0\n\nPrevious release can be found at [v0.5.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.5.0)\n\n## [terraform-provider-talos 0.6.0-alpha.2](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.6.0-alpha.2) (2024-09-02)\n\nWelcome to the v0.6.0-alpha.2 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Image Factory\n\nSupport for querying info from Image Factory and registering schematics is now supported via new Terraform resources.\n\n\n### Talos Cluster Health\n\n`talos_cluster_health` data source now has a way to skip running the Kubernetes components health check by setting `skip_kubernetes_checks` to `true`.\n\n\n### Talos Cluster Kubeconfig\n\n`talos_cluster_kubeconfig` data source is now deprecated and will be removed in the next minor release.\nUse `talos_cluster_kubeconfig` resource instead.\nThe `talos_cluster_kubeconfig` resource will regenerate kubernetes client config when the time to expiry is less than a month.\n\n\n### Talos Machine Configuration Data Source\n\n`talos_machine_configuration` data source now defaults to generating config with documentation and examples disabled.\n\nTo restore the previous behavior, set `docs` and `examples` attributes to `true`.\n\n\n### Talos Machine Configuration Apply\n\n`talos_machine_configuration_apply` resource now optionally supports resetting the machine back to maintenance mode.\n\n\n### Talos Machine Secrets\n\n`talos_machine_secrets` resource now regenerates client config when the time to expiry is less than a month.\n\n\n### Component Updates\n\nTalos sdk: v1.8.0-alpha.1\n\n\n### Contributors\n\n* Noel Georgi\n* Hippie Hacker\n\n### Changes\n<details><summary>16 commits</summary>\n<p>\n\n* [`858f7f3`](https://github.com/siderolabs/terraform-provider-talos/commit/858f7f3de9368604b8f18125420d6888606b21be) chore: bump deps\n* [`7af49b3`](https://github.com/siderolabs/terraform-provider-talos/commit/7af49b315e4b37b7a165c6ef5d5dc2830dc00a6f) chore: better health checks from talos sdk\n* [`063b7ae`](https://github.com/siderolabs/terraform-provider-talos/commit/063b7aeb9dc69782ec7cf541433f7b1eb92e4197) chore: default talos_machine_configuration docs and examples to false\n* [`80c5534`](https://github.com/siderolabs/terraform-provider-talos/commit/80c5534fbd876506201f21b50c950ce053402a55) chore: support filtering stable version\n* [`b9c7f5f`](https://github.com/siderolabs/terraform-provider-talos/commit/b9c7f5f8aedaca50a4e694e022cae456cd44d065) release(v0.6.0-alpha.1): prepare release\n* [`92fcb70`](https://github.com/siderolabs/terraform-provider-talos/commit/92fcb70cd9c1d6cfb5bd3ea159e56fa493fe62db) feat: add `talos_image_factory_url` data source\n* [`ffc8102`](https://github.com/siderolabs/terraform-provider-talos/commit/ffc8102dd7f7b0929dc54fa1f50afd9b2cfda6be) feat: add factory support\n* [`d6c2a0b`](https://github.com/siderolabs/terraform-provider-talos/commit/d6c2a0bc939de41252d97f09b8e9dfcff3377450) chore: fix goreleaser config\n* [`dcdcee6`](https://github.com/siderolabs/terraform-provider-talos/commit/dcdcee62f8d9429cc0416dfdb92dfc27391da0ee) release(v0.6.0-alpha.0): prepare release\n* [`d962913`](https://github.com/siderolabs/terraform-provider-talos/commit/d9629133c03ef09d5a6136b0e6cc1624a7ef4c28) chore: reset options for `machine_configuration_apply` resource\n* [`f26a591`](https://github.com/siderolabs/terraform-provider-talos/commit/f26a5911bdd243fd384a353de1c0140de256211c) chore: data source -> resource `talos_cluster_kubeconfig`\n* [`78fd0d3`](https://github.com/siderolabs/terraform-provider-talos/commit/78fd0d369ff401fbd795609cbbc2275f7d108bb0) chore: ignore version prefix for `talos_version`\n* [`11ae330`](https://github.com/siderolabs/terraform-provider-talos/commit/11ae33002bee7a3e319bc7f9ea7555ca3ebaa120) feat: support skipping k8s health checks\n* [`0fe1a6f`](https://github.com/siderolabs/terraform-provider-talos/commit/0fe1a6fe8d4440f72d7c553cf961b0de7267404b) docs: update description of `talos_cluster_health`\n* [`f6f1811`](https://github.com/siderolabs/terraform-provider-talos/commit/f6f1811e90c9eef91f562f1f8b15f78e984315a0) feat: regenerate talosconfig\n* [`501c78e`](https://github.com/siderolabs/terraform-provider-talos/commit/501c78eb7403012c90229bfc24399d0e1603289b) chore: bump deps\n</p>\n</details>\n\n### Changes since v0.6.0-alpha.1\n<details><summary>4 commits</summary>\n<p>\n\n* [`858f7f3`](https://github.com/siderolabs/terraform-provider-talos/commit/858f7f3de9368604b8f18125420d6888606b21be) chore: bump deps\n* [`7af49b3`](https://github.com/siderolabs/terraform-provider-talos/commit/7af49b315e4b37b7a165c6ef5d5dc2830dc00a6f) chore: better health checks from talos sdk\n* [`063b7ae`](https://github.com/siderolabs/terraform-provider-talos/commit/063b7aeb9dc69782ec7cf541433f7b1eb92e4197) chore: default talos_machine_configuration docs and examples to false\n* [`80c5534`](https://github.com/siderolabs/terraform-provider-talos/commit/80c5534fbd876506201f21b50c950ce053402a55) chore: support filtering stable version\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/blang/semver/v4**                                  v4.0.0 **_new_**\n* **github.com/hashicorp/terraform-plugin-docs**                  v0.19.0 -> v0.19.4\n* **github.com/hashicorp/terraform-plugin-framework**             v1.7.0 -> v1.11.0\n* **github.com/hashicorp/terraform-plugin-framework-validators**  v0.12.0 -> v0.13.0\n* **github.com/hashicorp/terraform-plugin-go**                    v0.22.1 -> v0.23.0\n* **github.com/hashicorp/terraform-plugin-log**                   v0.9.0 **_new_**\n* **github.com/hashicorp/terraform-plugin-sdk/v2**                v2.33.0 -> v2.34.0\n* **github.com/hashicorp/terraform-plugin-testing**               v1.7.0 -> v1.10.0\n* **github.com/siderolabs/gen**                                   v0.4.8 -> v0.5.0\n* **github.com/siderolabs/image-factory**                         9687413a9a85 **_new_**\n* **github.com/siderolabs/talos**                                 v1.8.0-alpha.2 **_new_**\n* **github.com/siderolabs/talos/pkg/machinery**                   v1.7.0 -> v1.8.0-alpha.2\n* **golang.org/x/mod**                                            v0.17.0 -> v0.20.0\n* **google.golang.org/grpc**                                      v1.63.2 -> v1.66.0\n* **k8s.io/client-go**                                            v0.29.3 -> v0.31.0\n\nPrevious release can be found at [v0.5.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.5.0)\n\n## [terraform-provider-talos 0.6.0-alpha.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.6.0-alpha.1) (2024-07-18)\n\nWelcome to the v0.6.0-alpha.1 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Image Factory\n\nSupport for querying info from Image Factory and registering schematics is now supported via new Terraform resources.\n\n\n### Talos Cluster Health\n\n`talos_cluster_health` data source now has a way to skip running the Kubernetes components health check by setting `skip_kubernetes_checks` to `true`.\n\n\n### Talos Cluster Kubeconfig\n\n`talos_cluster_kubeconfig` data source is now deprecated and will be removed in the next minor release.\nUse `talos_cluster_kubeconfig` resource instead.\nThe `talos_cluster_kubeconfig` resource will regenerate kubernetes client config when the time to expiry is less than a month.\n\n\n### Talos Machine Configuration Apply\n\n`talos_machine_configuration_apply` resource now optionally supports resetting the machine back to maintenance mode.\n\n\n### Talos Machine Secrets\n\n`talos_machine_secrets` resource now regenerates client config when the time to expiry is less than a month.\n\n\n### Component Updates\n\nTalos sdk: v1.8.0-alpha.1\n\n\n### Contributors\n\n* Noel Georgi\n\n### Changes\n<details><summary>11 commits</summary>\n<p>\n\n* [`92fcb70`](https://github.com/siderolabs/terraform-provider-talos/commit/92fcb70cd9c1d6cfb5bd3ea159e56fa493fe62db) feat: add `talos_image_factory_url` data source\n* [`ffc8102`](https://github.com/siderolabs/terraform-provider-talos/commit/ffc8102dd7f7b0929dc54fa1f50afd9b2cfda6be) feat: add factory support\n* [`d6c2a0b`](https://github.com/siderolabs/terraform-provider-talos/commit/d6c2a0bc939de41252d97f09b8e9dfcff3377450) chore: fix goreleaser config\n* [`dcdcee6`](https://github.com/siderolabs/terraform-provider-talos/commit/dcdcee62f8d9429cc0416dfdb92dfc27391da0ee) release(v0.6.0-alpha.0): prepare release\n* [`d962913`](https://github.com/siderolabs/terraform-provider-talos/commit/d9629133c03ef09d5a6136b0e6cc1624a7ef4c28) chore: reset options for `machine_configuration_apply` resource\n* [`f26a591`](https://github.com/siderolabs/terraform-provider-talos/commit/f26a5911bdd243fd384a353de1c0140de256211c) chore: data source -> resource `talos_cluster_kubeconfig`\n* [`78fd0d3`](https://github.com/siderolabs/terraform-provider-talos/commit/78fd0d369ff401fbd795609cbbc2275f7d108bb0) chore: ignore version prefix for `talos_version`\n* [`11ae330`](https://github.com/siderolabs/terraform-provider-talos/commit/11ae33002bee7a3e319bc7f9ea7555ca3ebaa120) feat: support skipping k8s health checks\n* [`0fe1a6f`](https://github.com/siderolabs/terraform-provider-talos/commit/0fe1a6fe8d4440f72d7c553cf961b0de7267404b) docs: update description of `talos_cluster_health`\n* [`f6f1811`](https://github.com/siderolabs/terraform-provider-talos/commit/f6f1811e90c9eef91f562f1f8b15f78e984315a0) feat: regenerate talosconfig\n* [`501c78e`](https://github.com/siderolabs/terraform-provider-talos/commit/501c78eb7403012c90229bfc24399d0e1603289b) chore: bump deps\n</p>\n</details>\n\n### Changes since v0.6.0-alpha.0\n<details><summary>2 commits</summary>\n<p>\n\n* [`92fcb70`](https://github.com/siderolabs/terraform-provider-talos/commit/92fcb70cd9c1d6cfb5bd3ea159e56fa493fe62db) feat: add `talos_image_factory_url` data source\n* [`ffc8102`](https://github.com/siderolabs/terraform-provider-talos/commit/ffc8102dd7f7b0929dc54fa1f50afd9b2cfda6be) feat: add factory support\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-docs**                  v0.19.0 -> v0.19.4\n* **github.com/hashicorp/terraform-plugin-framework**             v1.7.0 -> v1.10.0\n* **github.com/hashicorp/terraform-plugin-framework-validators**  v0.12.0 -> v0.13.0\n* **github.com/hashicorp/terraform-plugin-go**                    v0.22.1 -> v0.23.0\n* **github.com/hashicorp/terraform-plugin-log**                   v0.9.0 **_new_**\n* **github.com/hashicorp/terraform-plugin-sdk/v2**                v2.33.0 -> v2.34.0\n* **github.com/hashicorp/terraform-plugin-testing**               v1.7.0 -> v1.9.0\n* **github.com/siderolabs/gen**                                   v0.4.8 -> v0.5.0\n* **github.com/siderolabs/image-factory**                         8b4e0d9e9819 **_new_**\n* **github.com/siderolabs/talos**                                 980f9ebc0725 **_new_**\n* **github.com/siderolabs/talos/pkg/machinery**                   v1.7.0 -> v1.8.0-alpha.1\n* **golang.org/x/mod**                                            v0.17.0 -> v0.19.0\n* **google.golang.org/grpc**                                      v1.63.2 -> v1.65.0\n* **k8s.io/client-go**                                            v0.29.3 -> v0.31.0-beta.0\n\nPrevious release can be found at [v0.5.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.5.0)\n\n## [terraform-provider-talos 0.6.0-alpha.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.6.0-alpha.0) (2024-07-11)\n\nWelcome to the v0.6.0-alpha.0 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Talos Cluster Health\n\n`talos_cluster_health` data source now has a way to skip running the Kubernetes components health check by setting `skip_kubernetes_checks` to `true`.\n\n\n### Talos Cluster Kubeconfig\n\n`talos_cluster_kubeconfig` data source is now deprecated and will be removed in the next minor release.\nUse `talos_cluster_kubeconfig` resource instead.\nThe `talos_cluster_kubeconfig` resource will regenerate kubernetes client config when the time to expiry is less than a month.\n\n\n### Talos Machine Configuration Apply\n\n`talos_machine_configuration_apply` resource now optionally supports resetting the machine back to maintenance mode.\n\n\n### Talos Machine Secrets\n\n`talos_machine_secrets` resource now regenerates client config when the time to expiry is less than a month.\n\n\n### Component Updates\n\nTalos sdk: v1.8.0-alpha.1\n\n\n### Contributors\n\n* Noel Georgi\n* Dmitriy Matrenichev\n\n### Changes\n<details><summary>8 commits</summary>\n<p>\n\n* [`1908d9e`](https://github.com/siderolabs/terraform-provider-talos/commit/1908d9e085d4f0d55aa8d55888a01ed7b52e8295) release(v0.6.0-alpha.0): prepare release\n* [`d962913`](https://github.com/siderolabs/terraform-provider-talos/commit/d9629133c03ef09d5a6136b0e6cc1624a7ef4c28) chore: reset options for `machine_configuration_apply` resource\n* [`f26a591`](https://github.com/siderolabs/terraform-provider-talos/commit/f26a5911bdd243fd384a353de1c0140de256211c) chore: data source -> resource `talos_cluster_kubeconfig`\n* [`78fd0d3`](https://github.com/siderolabs/terraform-provider-talos/commit/78fd0d369ff401fbd795609cbbc2275f7d108bb0) chore: ignore version prefix for `talos_version`\n* [`11ae330`](https://github.com/siderolabs/terraform-provider-talos/commit/11ae33002bee7a3e319bc7f9ea7555ca3ebaa120) feat: support skipping k8s health checks\n* [`0fe1a6f`](https://github.com/siderolabs/terraform-provider-talos/commit/0fe1a6fe8d4440f72d7c553cf961b0de7267404b) docs: update description of `talos_cluster_health`\n* [`f6f1811`](https://github.com/siderolabs/terraform-provider-talos/commit/f6f1811e90c9eef91f562f1f8b15f78e984315a0) feat: regenerate talosconfig\n* [`501c78e`](https://github.com/siderolabs/terraform-provider-talos/commit/501c78eb7403012c90229bfc24399d0e1603289b) chore: bump deps\n</p>\n</details>\n\n### Changes from siderolabs/gen\n<details><summary>2 commits</summary>\n<p>\n\n* [`7654108`](https://github.com/siderolabs/gen/commit/7654108fe6ae15d4765584342709bc0bced6b3d6) chore: add hashtriemap implementation\n* [`8485864`](https://github.com/siderolabs/gen/commit/84858640dc9c3032219380885283b995d4f2b0d1) chore: optimize maps.Values and maps.Keys\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-docs**       v0.19.0 -> v0.19.4\n* **github.com/hashicorp/terraform-plugin-framework**  v1.7.0 -> v1.9.0\n* **github.com/hashicorp/terraform-plugin-go**         v0.22.1 -> v0.23.0\n* **github.com/hashicorp/terraform-plugin-log**        v0.9.0 **_new_**\n* **github.com/hashicorp/terraform-plugin-sdk/v2**     v2.33.0 -> v2.34.0\n* **github.com/hashicorp/terraform-plugin-testing**    v1.7.0 -> v1.8.0\n* **github.com/siderolabs/gen**                        v0.4.8 -> v0.5.0\n* **github.com/siderolabs/talos/pkg/machinery**        v1.7.0 -> v1.8.0-alpha.1\n* **golang.org/x/mod**                                 v0.17.0 -> v0.19.0\n* **google.golang.org/grpc**                           v1.63.2 -> v1.65.0\n* **k8s.io/client-go**                                 v0.29.3 -> v0.31.0-alpha.3\n\nPrevious release can be found at [v0.5.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.5.0)\n\n## [terraform-provider-talos 0.4.0-alpha.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.4.0-alpha.0) (2023-08-30)\n\nWelcome to the v0.4.0-alpha.0 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Talos Cluster Health data source\n\n`talos_cluster_health` data source has been added and the `wait` parameter from the `talos_cluster_kubeconfig` data source is now deprecated.\n\n\n### Component Updates\n\nTalos sdk: v1.6.0-alpha.0\n\n\n### Contributors\n\n* Noel Georgi\n* Dmitriy Matrenichev\n\n### Changes\n<details><summary>4 commits</summary>\n<p>\n\n* [`1c918e6`](https://github.com/siderolabs/terraform-provider-talos/commit/1c918e65b10764b1ed5286193ac661f3daec51d9) chore: add conform\n* [`ed36726`](https://github.com/siderolabs/terraform-provider-talos/commit/ed3672669b20c7fd911088609952f8e036f38a1f) feat: add `talos_cluster_health` data source.\n* [`5ac7183`](https://github.com/siderolabs/terraform-provider-talos/commit/5ac7183f33a425e17821f1a294a3133daa09e7fa) fix: node/endpoint were swapped for some resources.\n* [`713ac46`](https://github.com/siderolabs/terraform-provider-talos/commit/713ac4686a3e00e135cab7ea533da7319522dddd) fix: creation of talos client\n</p>\n</details>\n\n### Changes from siderolabs/gen\n<details><summary>1 commit</summary>\n<p>\n\n* [`36a3ae3`](https://github.com/siderolabs/gen/commit/36a3ae312ce03876b2c961a1bcb4ef4c221593d7) feat: update module\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-framework**  v1.3.4 -> v1.3.5\n* **github.com/hashicorp/terraform-plugin-sdk/v2**     v2.27.0 -> v2.28.0\n* **github.com/siderolabs/gen**                        v0.4.5 -> v0.4.6\n* **github.com/siderolabs/talos/pkg/machinery**        v1.5.0 -> v1.6.0-alpha.0\n* **k8s.io/client-go**                                 v0.28.0 -> v0.28.1\n\nPrevious release can be found at [v0.3.2](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.3.2)\n\n## [terraform-provider-talos 0.3.0-beta.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.3.0-beta.0) (2023-08-07)\n\nWelcome to the 0.3.0-beta.0 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Component Updates\n\nTalos sdk: v1.5.0-beta.0\n\n\n### Contributors\n\n* Noel Georgi\n* Ole-Martin Bratteng\n* Spencer Smith\n\n### Changes\n<details><summary>5 commits</summary>\n<p>\n\n* [`3f02af3`](https://github.com/siderolabs/terraform-provider-talos/commit/3f02af32747ab97d56d274eecbb3cc12bdaa7d1c) feat: update to talos 1.5 sdk\n* [`ff0e2ad`](https://github.com/siderolabs/terraform-provider-talos/commit/ff0e2adec13192716b9cf2180baa1bff2843387d) fix: ci failures due to TF state removal\n* [`ee150ce`](https://github.com/siderolabs/terraform-provider-talos/commit/ee150ce9925aac49e324ba4909104cba5a9ad50e) docs: update link to contrib repo\n* [`df4f876`](https://github.com/siderolabs/terraform-provider-talos/commit/df4f876ce18e8239bb1cabec7437a0f62ed1f5f7) docs: replace `type` with `machine_type`\n* [`f6c8715`](https://github.com/siderolabs/terraform-provider-talos/commit/f6c871516635dbb402bfe24bd47759537c7fee46) chore: bump deps\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/siderolabs/talos/pkg/machinery**  v1.4.7 -> v1.5.0-beta.0\n\nPrevious release can be found at [v0.2.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.2.1)\n\n## [terraform-provider-talos 0.2.0-alpha.2](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.2.0-alpha.2) (2023-04-14)\n\nWelcome to the v0.2.0-alpha.2 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Data Sources\n\n`talos_machine_disks` data source is added to list disks on a machine.\n\n\n### Provider Changes\n\nThis version of the provider includes some breaking changes. Make sure to follow the provider upgrade guide at https://registry.terraform.io/providers/siderolabs/talos/latest/docs/guides/version-0.2-upgrade.html\n\n\n### Component Updates\n\nTalos sdk: v1.4.0-beta.1\n\n\n### Contributors\n\n* Andrey Smirnov\n* Andrey Smirnov\n* Artem Chernyshev\n* Dmitriy Matrenichev\n* Artem Chernyshev\n* Noel Georgi\n* Serge Logvinov\n* Andrew Rynhard\n* Andrew Rynhard\n* Matt Zahorik\n* Olli Janatuinen\n* Seán C McCord\n* Spencer Smith\n\n### Changes\n<details><summary>2 commits</summary>\n<p>\n\n* [`187e434`](https://github.com/siderolabs/terraform-provider-talos/commit/187e434235da1107eaefc1656147900fa8c1d082) feat: `talos_machine_disks` data source\n* [`a29e1e7`](https://github.com/siderolabs/terraform-provider-talos/commit/a29e1e7894776a4c796712163e64084e73b1ffa7) fix: handle unknown types at plan time\n</p>\n</details>\n\n### Changes from siderolabs/gen\n<details><summary>9 commits</summary>\n<p>\n\n* [`214c1ef`](https://github.com/siderolabs/gen/commit/214c1efe795cf426e5ebcc48cb305bfc7a16fdb8) chore: set `slice.Filter` result slice cap to len\n* [`8e89b1e`](https://github.com/siderolabs/gen/commit/8e89b1ede9f35ff4c18a41ee44a69259181c892b) feat: add GetOrCreate and GetOrCall methods\n* [`7c7ccc3`](https://github.com/siderolabs/gen/commit/7c7ccc3d973621b2fa7adfef10241ecc1f7a644d) feat: introduce channel SendWithContext\n* [`b3b6db8`](https://github.com/siderolabs/gen/commit/b3b6db858cb6ce46005edeb70776608e3f9bc402) fix: fix Copy documentation and implementation\n* [`521f737`](https://github.com/siderolabs/gen/commit/521f7371f40556ddce7f730c8de5e1888e40b621) feat: add xerrors package which contains additions to the std errors\n* [`726e066`](https://github.com/siderolabs/gen/commit/726e066dcb35c86f82866097bed806f22b936292) fix: rename tuples.go to pair.go and set proper package name\n* [`d8d7d25`](https://github.com/siderolabs/gen/commit/d8d7d25ce9a588609c00cb798206a01a866bf7a6) chore: minor additions\n* [`338a650`](https://github.com/siderolabs/gen/commit/338a65065f92eb6426a66c4a88a0cc02cc02e529) chore: add initial implementation and documentation\n* [`4fd8667`](https://github.com/siderolabs/gen/commit/4fd866707052c792a6adccbc28efec5debdd18a8) Initial commit\n</p>\n</details>\n\n### Changes from siderolabs/go-blockdevice\n<details><summary>59 commits</summary>\n<p>\n\n* [`b4386f3`](https://github.com/siderolabs/go-blockdevice/commit/b4386f37510bc25e39b231fa587288ad0abf0b68) feat: make disk utils read subsystem information from the `/sys/block`\n* [`8c7ea19`](https://github.com/siderolabs/go-blockdevice/commit/8c7ea1910b27e0660e3e1a6f98b9f7e24bc11ff0) fix: blockdevice size is reported by Linux in 512 blocks always\n* [`e52e012`](https://github.com/siderolabs/go-blockdevice/commit/e52e012a6935a99a1b344a898f281cf7d6a78e69) feat: add ext4 filesystem detection logic\n* [`694ac62`](https://github.com/siderolabs/go-blockdevice/commit/694ac62b3dcf995beea95a77659fdc6064b457b3) chore: update imports to siderolabs, rekres\n* [`dcf6044`](https://github.com/siderolabs/go-blockdevice/commit/dcf6044c906b36f183e11b6553458c680126d1d9) chore: rekres and rename\n* [`9c4af49`](https://github.com/siderolabs/go-blockdevice/commit/9c4af492cc17279f0281fcd271e7423be78442bb) fix: cryptsetup remove slot\n* [`74ea471`](https://github.com/siderolabs/go-blockdevice/commit/74ea47109c4525bec139640fed6354ad3097f5fb) feat: add freebsd stubs\n* [`9fa801c`](https://github.com/siderolabs/go-blockdevice/commit/9fa801cf4da184e3560b9a18ba43d13316f172f9) feat: add ReadOnly attribute to Disk\n* [`fccee8b`](https://github.com/siderolabs/go-blockdevice/commit/fccee8bb082b105cb60db40cb01636efc3241b5f) chore: rekres the source, fix issues\n* [`d9c3a27`](https://github.com/siderolabs/go-blockdevice/commit/d9c3a273886113e24809ef1e9930fc982318217d) feat: support probing FAT12/FAT16 filesystems\n* [`b374eb4`](https://github.com/siderolabs/go-blockdevice/commit/b374eb48148dc92a82d8bf9540432bb8531f73f3) fix: align partition to 1M boundary by default\n* [`ec428fe`](https://github.com/siderolabs/go-blockdevice/commit/ec428fed2ecd5a389833a88f8dc333762816db99) fix: lookup filesystem labels on the actual device path\n* [`7b9de26`](https://github.com/siderolabs/go-blockdevice/commit/7b9de26bc6bc3d54b95bd8e8fb3aade4b45adc6c) feat: read symlink fullpath in block device list function\n* [`6928ee4`](https://github.com/siderolabs/go-blockdevice/commit/6928ee43c3034549e32f000f8b7bc16a6ebb7ed4) refactor: rewrite GPT serialize/deserialize functions\n* [`0c7e429`](https://github.com/siderolabs/go-blockdevice/commit/0c7e4296e01b3df815a935db3e30de6b9d4cc1d1) refactor: simplify middle endian functions\n* [`15b182d`](https://github.com/siderolabs/go-blockdevice/commit/15b182db0cd233b163ed83d1724c7e28cf29d71a) fix: return partition table not exist when trying to read an empty dev\n* [`b9517d5`](https://github.com/siderolabs/go-blockdevice/commit/b9517d51120d385f97b0026f99ce3c4782940c37) fix: resize partition\n* [`70d2865`](https://github.com/siderolabs/go-blockdevice/commit/70d28650b398a14469cbb5356417355b0ba62956) fix: try to find cdrom disks\n* [`667bf53`](https://github.com/siderolabs/go-blockdevice/commit/667bf539b99ac34b629a0103ef7a7278a5a5f35d) fix: revert gpt partition not found\n* [`d7d4cdd`](https://github.com/siderolabs/go-blockdevice/commit/d7d4cdd7ac56c82caab19246b5decd59f12195eb) fix: gpt partition not found\n* [`33afba3`](https://github.com/siderolabs/go-blockdevice/commit/33afba347c0dce38a436c46a0aac26d2f99427c1) fix: also open in readonly mode when running `All` lookup method\n* [`e367f9d`](https://github.com/siderolabs/go-blockdevice/commit/e367f9dc7fa935f11672de0fdc8a89429285a07a) feat: make probe always open blockdevices in readonly mode\n* [`d981156`](https://github.com/siderolabs/go-blockdevice/commit/d9811569588ba44be878a00ce316f59a37abed8b) fix: allow Build for Windows\n* [`fe24303`](https://github.com/siderolabs/go-blockdevice/commit/fe2430349e9d734ce6dbf4e7b2e0f8a37bb22679) fix: perform correct PMBR partition calculations\n* [`2ec0c3c`](https://github.com/siderolabs/go-blockdevice/commit/2ec0c3cc0ff5ff705ed5c910ca1bcd5d93c7b102) fix: preserve the PMBR bootable flag when opening GPT partition\n* [`87816a8`](https://github.com/siderolabs/go-blockdevice/commit/87816a81cefc728cfe3cb221b476d8ed4b609fd8) feat: align partition to minimum I/O size\n* [`c34b59f`](https://github.com/siderolabs/go-blockdevice/commit/c34b59fb33a7ad8be18bb19bc8c8d8294b4b3a78) feat: expose more encryption options in the LUKS module\n* [`30c2bc3`](https://github.com/siderolabs/go-blockdevice/commit/30c2bc3cb62af52f0aea9ce347923b0649fb7928) feat: mark MBR bootable\n* [`1292574`](https://github.com/siderolabs/go-blockdevice/commit/1292574643e06512255fb0f45107e0c296eb5a3b) fix: make disk type matcher parser case insensitive\n* [`b77400e`](https://github.com/siderolabs/go-blockdevice/commit/b77400e0a7261bf25da77c1f28c2f393f367bfa9) fix: properly detect nvme and sd card disk types\n* [`1d830a2`](https://github.com/siderolabs/go-blockdevice/commit/1d830a25f64f6fb96a1bedd800c0b40b107dc833) fix: revert mark the EFI partition in PMBR as bootable\n* [`bec914f`](https://github.com/siderolabs/go-blockdevice/commit/bec914ffdda42abcfe642bc2cdfc9fcda56a74ee) fix: mark the EFI partition in PMBR as bootable\n* [`776b37d`](https://github.com/siderolabs/go-blockdevice/commit/776b37d31de0781f098f5d9d1894fbea3f2dfa1d) feat: add options to probe disk by various sysblock parameters\n* [`bb3ad73`](https://github.com/siderolabs/go-blockdevice/commit/bb3ad73f69836acc2785ec659435e24a531359e7) fix: align partition start to physical sector size\n* [`8f976c2`](https://github.com/siderolabs/go-blockdevice/commit/8f976c2031108651738ebd4db69fb09758754a28) feat: replace exec.Command with go-cmd module\n* [`1cf7f25`](https://github.com/siderolabs/go-blockdevice/commit/1cf7f252c38cf11ef07723de2debc27d1da6b520) fix: properly handle no child processes error from cmd.Wait\n* [`04a9851`](https://github.com/siderolabs/go-blockdevice/commit/04a98510c07fe8477f598befbfe6eaec4f4b73a2) feat: implement luks encryption provider\n* [`b0375e4`](https://github.com/siderolabs/go-blockdevice/commit/b0375e4267fdc6108bd9ff7a5dc97b80cd924b1d) feat: add an option to open block device with exclusive flock\n* [`5a1c7f7`](https://github.com/siderolabs/go-blockdevice/commit/5a1c7f768e016c93f6c0be130ffeaf34109b5b4d) refactor: add devname into gpt.Partition, refactor probe package\n* [`f2728a5`](https://github.com/siderolabs/go-blockdevice/commit/f2728a581972be977d863d5d9177a873b8f3fc7b) fix: keep contents of PMBR when writing it\n* [`2878460`](https://github.com/siderolabs/go-blockdevice/commit/2878460b54e8b8c3846c6a882ca9e1472c8b6b3b) fix: write second copy of partition entries\n* [`943b08b`](https://github.com/siderolabs/go-blockdevice/commit/943b08bc32a2156cffb23e92b8be9288de4a7421) fix: blockdevice reset should read partition table from disk\n* [`5b4ee44`](https://github.com/siderolabs/go-blockdevice/commit/5b4ee44cfd434a03ec2d7167bcc56d0f164c3fa2) fix: ignore `/dev/ram` devices\n* [`98754ec`](https://github.com/siderolabs/go-blockdevice/commit/98754ec2bb200acc9e9e573fa766754d60e25ff2) refactor: rewrite GPT library\n* [`2a1baad`](https://github.com/siderolabs/go-blockdevice/commit/2a1baadffdf8c9b65355e9af6e744aeab838c9db) fix: correctly build paths for `mmcblk` devices\n* [`8076344`](https://github.com/siderolabs/go-blockdevice/commit/8076344a95021f25ab5d1fbf5ea4fefc790f6c3c) fix: return proper disk size from GetDisks function\n* [`8742133`](https://github.com/siderolabs/go-blockdevice/commit/874213371a3fb0925aab45cbba68a957e3319525) chore: add common method to list available disks using /sys/block\n* [`c4b5833`](https://github.com/siderolabs/go-blockdevice/commit/c4b583363d63503ed7e4adb9a9fa64335f7e198d) feat: implement \"fast\" wipe\n* [`b4e67d7`](https://github.com/siderolabs/go-blockdevice/commit/b4e67d73d70d8dc06aa2b4986622dcb854dfc40c) feat: return resize status from Resize() function\n* [`ceae64e`](https://github.com/siderolabs/go-blockdevice/commit/ceae64edb3a591c6f6bbd75b1149d1cfe426dd8e) fix: sync kernel partition table incrementally\n* [`2cb9516`](https://github.com/siderolabs/go-blockdevice/commit/2cb95165aa67b0b839863b5ad89920c3ac7e2c82) fix: return correct error value from blkpg functions\n* [`cebe43d`](https://github.com/siderolabs/go-blockdevice/commit/cebe43d1fdc1e509437198e578faa9d5a804cc37) refactor: expose `InsertAt` method via interface\n* [`c40dcd8`](https://github.com/siderolabs/go-blockdevice/commit/c40dcd80c50b41c1f2a60ea6aa9d5fb3d3b180a3) fix: properly inform kernel about partition deletion\n* [`bb8ac5d`](https://github.com/siderolabs/go-blockdevice/commit/bb8ac5d6a25e279e16213f585dc8d02ba6ed645f) feat: implement disk wiping via several methods\n* [`23fb7dc`](https://github.com/siderolabs/go-blockdevice/commit/23fb7dc755325cfe12e48c8e8e31bebab9ddc2bc) feat: expose partition name (label)\n* [`ff3a821`](https://github.com/siderolabs/go-blockdevice/commit/ff3a8210be999b8bfb2019f19f8a8b50901c64cc) feat: implement 'InsertAt' method to insert partitions at any position\n* [`3d1ce4f`](https://github.com/siderolabs/go-blockdevice/commit/3d1ce4fc859fa614a4c5c54a10c0f5f4fce38bb6) fix: calculate last lba of partition correctly\n* [`b71540f`](https://github.com/siderolabs/go-blockdevice/commit/b71540f6c398e958bdb7c118396a736419f735d4) feat: copy initial version from talos-systems/talos\n* [`ca3c078`](https://github.com/siderolabs/go-blockdevice/commit/ca3c078da95e6497c9d41667dc242e32682e517d) Initial commit\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/dustin/go-humanize**         v1.0.1 **_new_**\n* **github.com/siderolabs/gen**             v0.4.3 **_new_**\n* **github.com/siderolabs/go-blockdevice**  v0.4.4 **_new_**\n* **k8s.io/client-go**                      v0.26.3 -> v0.27.0\n\nPrevious release can be found at [v0.2.0-alpha.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.2.0-alpha.1)\n\n## [terraform-provider-talos 0.2.0-alpha.1](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.2.0-alpha.1) (2023-04-12)\n\nWelcome to the v0.2.0-alpha.1 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Provider Changes\n\nThis version of the provider includes some breaking changes. Make sure to follow the provider upgrade guide at https://registry.terraform.io/providers/siderolabs/talos/latest/docs/guides/version-0.2-upgrade.html\n\n\n### Component Updates\n\nTalos sdk: v1.4.0-beta.1\n\n\n### Contributors\n\n* Noel Georgi\n\n### Changes\n<details><summary>1 commit</summary>\n<p>\n\n* [`96aeedd`](https://github.com/siderolabs/terraform-provider-talos/commit/96aeedd4bca46ced42bc98220e809940b773ce5d) docs: fix rendering of website\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/siderolabs/talos/pkg/machinery**  v1.4.0-beta.0 -> v1.4.0-beta.1\n\nPrevious release can be found at [v0.2.0-alpha.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.2.0-alpha.0)\n\n\n## [terraform-provider-talos 0.2.0-alpha.0](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.2.0-alpha.0) (2023-04-10)\n\nWelcome to the v0.2.0-alpha.0 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Provider Changes\n\nThis version of the provider includes some breaking changes. Make sure to follow the provider upgrade guide at https://registry.terraform.io/providers/siderolabs/talos/latest/docs/guides/version-0.2-upgrade\n\n\n### Component Updates\n\nTalos sdk: v1.4.0-beta.0\n\n\n### Contributors\n\n* Andrey Smirnov\n* Noel Georgi\n* Alexey Palazhchenko\n* Andrey Smirnov\n* Spencer Smith\n* Andrew Rynhard\n* Artem Chernyshev\n* Robert Wunderer\n* Serge Logvinov\n\n### Changes\n<details><summary>10 commits</summary>\n<p>\n\n* [`6b2182b`](https://github.com/siderolabs/terraform-provider-talos/commit/6b2182be4015eb21d936930cfa108159b3fa16f6) chore: ci cleanup\n* [`ea07caa`](https://github.com/siderolabs/terraform-provider-talos/commit/ea07caa6f39d159b286db76c525ed7cb1892f1e6) feat: code cleanup and tests\n* [`4e5c210`](https://github.com/siderolabs/terraform-provider-talos/commit/4e5c210c219ddeb0ccf68cd80cb2988ce0ab5ccd) feat: use new tf sdk\n* [`d1438b7`](https://github.com/siderolabs/terraform-provider-talos/commit/d1438b71d94b0ee0d0f3f5feb12317344c6e2a3e) chore: bump talos machinery\n* [`aed502e`](https://github.com/siderolabs/terraform-provider-talos/commit/aed502e51945bad2493c521672a52111fcd1eca6) fix: state update required two runs\n* [`dc00baa`](https://github.com/siderolabs/terraform-provider-talos/commit/dc00baad8d85e2786789ea03ac8e35d0b613bd70) fix: force new talosconfig if endpoints or nodes change\n* [`b7d84ba`](https://github.com/siderolabs/terraform-provider-talos/commit/b7d84ba4e297271b1599de20310640c4ebffccb9) chore: update registry index file, remove example\n* [`158dbbd`](https://github.com/siderolabs/terraform-provider-talos/commit/158dbbde42326fed9ada2a97a2a25c625c0a783e) docs: re-word `talos_version`\n* [`f3b4a5b`](https://github.com/siderolabs/terraform-provider-talos/commit/f3b4a5b24362c264a642e5bc5a28bba0e70a86fc) chore: bump deps\n* [`d2b6df0`](https://github.com/siderolabs/terraform-provider-talos/commit/d2b6df03e44a9150445209d3bd118c5d4417547c) docs: clarify meaning of `talos_version` in `machine_configuration` resources\n</p>\n</details>\n\n### Changes from siderolabs/crypto\n<details><summary>27 commits</summary>\n<p>\n\n* [`c3225ee`](https://github.com/siderolabs/crypto/commit/c3225eee603a8d1218c67e1bfe33ddde7953ed74) feat: allow CSR template subject field to be overridden\n* [`8570669`](https://github.com/siderolabs/crypto/commit/85706698dac8cddd0e9f41006bed059347d2ea26) chore: rename to siderolabs/crypto\n* [`e9df1b8`](https://github.com/siderolabs/crypto/commit/e9df1b8ca74c6efdc7f72191e5d2613830162fd5) feat: add support for generating keys from RSA-SHA256 CAs\n* [`510b0d2`](https://github.com/siderolabs/crypto/commit/510b0d2753a89170d0c0f60e052a66484997a5b2) chore: add json tags\n* [`6fa2d93`](https://github.com/siderolabs/crypto/commit/6fa2d93d0382299d5471e0de8e831c923398aaa8) fix: deepcopy nil fields as `nil`\n* [`9a63cba`](https://github.com/siderolabs/crypto/commit/9a63cba8dabd278f3080fa8c160613efc48c43f8) fix: add back support for generating ECDSA keys with P-256 and SHA512\n* [`893bc66`](https://github.com/siderolabs/crypto/commit/893bc66e4716a4cb7d1d5e66b5660ffc01f22823) fix: use SHA256 for ECDSA-P256\n* [`deec8d4`](https://github.com/siderolabs/crypto/commit/deec8d47700e10e3ea813bdce01377bd93c83367) chore: implement DeepCopy methods for PEMEncoded* types\n* [`d3cb772`](https://github.com/siderolabs/crypto/commit/d3cb77220384b3a3119a6f3ddb1340bbc811f1d1) feat: make possible to change KeyUsage\n* [`6bc5bb5`](https://github.com/siderolabs/crypto/commit/6bc5bb50c52767296a1b1cab6580e3fcf1358f34) chore: remove unused argument\n* [`cd18ef6`](https://github.com/siderolabs/crypto/commit/cd18ef62eb9f65d8b6730a2eb73e47e629949e1b) feat: add support for several organizations\n* [`97c888b`](https://github.com/siderolabs/crypto/commit/97c888b3924dd5ac70b8d30dd66b4370b5ab1edc) chore: add options to CSR\n* [`7776057`](https://github.com/siderolabs/crypto/commit/7776057f5086157873f62f6a21ec23fa9fd86e05) chore: fix typos\n* [`80df078`](https://github.com/siderolabs/crypto/commit/80df078327030af7e822668405bb4853c512bd7c) chore: remove named result parameters\n* [`15bdd28`](https://github.com/siderolabs/crypto/commit/15bdd282b74ac406ab243853c1b50338a1bc29d0) chore: minor updates\n* [`4f80b97`](https://github.com/siderolabs/crypto/commit/4f80b976b640d773fb025d981bf85bcc8190815b) fix: verify CSR signature before issuing a certificate\n* [`39584f1`](https://github.com/siderolabs/crypto/commit/39584f1b6e54e9966db1f16369092b2215707134) feat: support for key/certificate types RSA, Ed25519, ECDSA\n* [`cf75519`](https://github.com/siderolabs/crypto/commit/cf75519cab82bd1b128ae9b45107c6bb422bd96a) fix: function NewKeyPair should create certificate with proper subject\n* [`751c95a`](https://github.com/siderolabs/crypto/commit/751c95aa9434832a74deb6884cff7c5fd785db0b) feat: add 'PEMEncodedKey' which allows to transport keys in YAML\n* [`562c3b6`](https://github.com/siderolabs/crypto/commit/562c3b66f89866746c0ba47927c55f41afed0f7f) feat: add support for public RSA key in RSAKey\n* [`bda0e9c`](https://github.com/siderolabs/crypto/commit/bda0e9c24e80c658333822e2002e0bc671ac53a3) feat: enable more conversions between encoded and raw versions\n* [`e0dd56a`](https://github.com/siderolabs/crypto/commit/e0dd56ac47456f85c0b247999afa93fb87ebc78b) feat: add NotBefore option for x509 cert creation\n* [`12a4897`](https://github.com/siderolabs/crypto/commit/12a489768a6bb2c13e16e54617139c980f99a658) feat: add support for SPKI fingerprint generation and matching\n* [`d0c3eef`](https://github.com/siderolabs/crypto/commit/d0c3eef149ec9b713e7eca8c35a6214bd0a64bc4) fix: implement NewKeyPair\n* [`196679e`](https://github.com/siderolabs/crypto/commit/196679e9ec77cb709db54879ddeddd4eaafaea01) feat: move `pkg/grpc/tls` from `github.com/talos-systems/talos` as `./tls`\n* [`1ff6242`](https://github.com/siderolabs/crypto/commit/1ff6242c91bb298ceeb4acd65685cba952fe4178) chore: initial version as imported from talos-systems/talos\n* [`835063e`](https://github.com/siderolabs/crypto/commit/835063e055b28a525038b826a6d80cbe76402414) chore: initial commit\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/hashicorp/terraform-plugin-framework**             v1.2.0 **_new_**\n* **github.com/hashicorp/terraform-plugin-framework-timeouts**    v0.3.1 **_new_**\n* **github.com/hashicorp/terraform-plugin-framework-validators**  v0.10.0 **_new_**\n* **github.com/hashicorp/terraform-plugin-go**                    v0.15.0 **_new_**\n* **github.com/hashicorp/terraform-plugin-sdk/v2**                v2.25.0 -> v2.26.1\n* **github.com/hashicorp/terraform-plugin-testing**               v1.2.0 **_new_**\n* **github.com/siderolabs/crypto**                                v0.4.0 **_new_**\n* **github.com/siderolabs/talos/pkg/machinery**                   v1.3.6 -> v1.4.0-beta.0\n* **golang.org/x/mod**                                            v0.10.0 **_new_**\n* **google.golang.org/grpc**                                      v1.51.0 -> v1.54.0\n* **k8s.io/client-go**                                            v0.26.3 **_new_**\n\nPrevious release can be found at [v0.1.2](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.2)\n\n## [terraform-provider-talos 0.1.0-alpha.12](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.12) (2022-12-16)\n\nWelcome to the v0.1.0-alpha.12 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Fixes\n\nFixed an issue with the provider when using a secure Talos client.\n\n\n### Contributors\n\n* Noel Georgi\n\n### Changes\n<details><summary>1 commit</summary>\n<p>\n\n* [`3c80f59`](https://github.com/siderolabs/terraform-provider-talos/commit/3c80f59ad7a8514b5481c84ca0d210c62ea06bcc) fix: handling talos secure client\n</p>\n</details>\n\n### Dependency Changes\n\nThis release has no dependency changes\n\nPrevious release can be found at [v0.1.0-alpha.11](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.11)\n\n## [terraform-provider-talos 0.1.0-alpha.11](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.11) (2022-12-09)\n\nWelcome to the v0.1.0-alpha.11 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Component Updates\n\nTalos sdk: v1.2.7\n\n\n### Contributors\n\n\n### Changes\n<details><summary>0 commit</summary>\n<p>\n\n</p>\n</details>\n\n### Dependency Changes\n\nThis release has no dependency changes\n\nPrevious release can be found at [v0.1.0-alpha.10](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.10)\n\n## [terraform-provider-talos 0.1.0-alpha.10](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.10) (2022-11-02)\n\nWelcome to the v0.1.0-alpha.10 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Component Updates\n\nTalos sdk: v1.2.6\n\n\n### Contributors\n\n\n### Changes\n<details><summary>0 commit</summary>\n<p>\n\n</p>\n</details>\n\n### Dependency Changes\n\nThis release has no dependency changes\n\nPrevious release can be found at [v0.1.0-alpha.9](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.9)\n\n## [terraform-provider-talos 0.1.0-alpha.9](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.9) (2022-10-18)\n\nWelcome to the v0.1.0-alpha.9 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Component Updates\n\nTalos sdk: v1.2.5\n\n\n### Contributors\n\n\n### Changes\n<details><summary>0 commit</summary>\n<p>\n\n</p>\n</details>\n\n### Dependency Changes\n\nThis release has no dependency changes\n\nPrevious release can be found at [v0.1.0-alpha.8](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.8)\n\n## [terraform-provider-talos 1.2.4](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v1.2.4) (2022-10-18)\n\nWelcome to the v1.2.4 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Component Updates\n\nTalos sdk: v1.2.4\n\n\n### Contributors\n\n* Dmitriy Matrenichev\n* Noel Georgi\n\n### Changes\n<details><summary>1 commit</summary>\n<p>\n\n* [`1c7975d`](https://github.com/siderolabs/terraform-provider-talos/commit/1c7975d1392406fa10a1a225e426e005d699c73e) chore: move to `gen` go pkg\n</p>\n</details>\n\n### Changes from siderolabs/gen\n<details><summary>2 commits</summary>\n<p>\n\n* [`338a650`](https://github.com/siderolabs/gen/commit/338a65065f92eb6426a66c4a88a0cc02cc02e529) chore: add initial implementation and documentation\n* [`4fd8667`](https://github.com/siderolabs/gen/commit/4fd866707052c792a6adccbc28efec5debdd18a8) Initial commit\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/siderolabs/gen**  v0.1.0 **_new_**\n\nPrevious release can be found at [v0.1.0-alpha.7](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.7)\n\n## [terraform-provider-talos 0.1.0-alpha.7](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.7) (2022-09-20)\n\nWelcome to the v0.1.0-alpha.7 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Contributors\n\n* Noel Georgi\n\n### Changes\n<details><summary>1 commit</summary>\n<p>\n\n* [`79594a6`](https://github.com/siderolabs/terraform-provider-talos/commit/79594a60b231966f68be2e39c01990e209176d6b) chore: bump talos to v1.2.3\n</p>\n</details>\n\n### Dependency Changes\n\nThis release has no dependency changes\n\nPrevious release can be found at [v0.1.0-alpha.6](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.6)\n\n## [terraform-provider-talos 0.1.0-alpha.6](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.6) (2022-09-15)\n\nWelcome to the v0.1.0-alpha.6 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Talos Provider\n\nThe Talos provider now requires `endpoint` and `node` to be set for `talos_machine_configuration_apply`, `talos_machine_bootstrap`, `talos_cluster_kubeconfig` resources.\nThe `endpoints` and `nodes` arguments are removed for the above resources.\n\nThis release also fixes a bug when multiple endpoitns were specified in the Talos client config.\n\n\n\n### Contributors\n\n\n### Changes\n<details><summary>0 commit</summary>\n<p>\n\n</p>\n</details>\n\n### Dependency Changes\n\nThis release has no dependency changes\n\nPrevious release can be found at [v0.1.0-alpha.5](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.5)\n\n## [terraform-provider-talos 0.1.0-alpha.5](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.5) (2022-09-15)\n\nWelcome to the v0.1.0-alpha.5 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Talos Provider\n\nThe Talos provider now requires `endpoint` and `node` to be set for `talos_machine_configuration_apply`, `talos_machine_bootstrap`, `talos_cluster_kubeconfig` resources.\nThe `endpoints` and `nodes` arguments are removed for the above resources.\n\nThis release also fixes a bug when multiple endpoitns were specified in the Talos client config.\n\n\n\n### Contributors\n\n\n### Changes\n<details><summary>0 commit</summary>\n<p>\n\n</p>\n</details>\n\n### Dependency Changes\n\nThis release has no dependency changes\n\nPrevious release can be found at [v0.1.0-alpha.4](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.4)\n\n## [terraform-provider-talos 0.1.0-alpha.4](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.4) (2022-09-15)\n\nWelcome to the v0.1.0-alpha.4 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Talos Provider\n\nThe Talos provider now requires `endpoint` and `node` to be set for `talos_machine_configuration_apply`, `talos_machine_bootstrap`, `talos_cluster_kubeconfig` resources.\nThe `endpoints` and `nodes` arguments are removed for the above resources.\n\nThis release also fixes a bug when multiple endpoitns were specified in the Talos client config.\n\n\n\n### Contributors\n\n* Noel Georgi\n* Nahuel Pastorale\n\n### Changes\n<details><summary>3 commits</summary>\n<p>\n\n* [`ea5a4ba`](https://github.com/siderolabs/terraform-provider-talos/commit/ea5a4bab1d86f20fc832fd4ffacf5978699a716e) release(v0.1.0-alpha.4): prepare release\n* [`b9111db`](https://github.com/siderolabs/terraform-provider-talos/commit/b9111db42dade59000b26b313f7b7f0d5e6dc083) fix: client operations\n* [`e2d04ac`](https://github.com/siderolabs/terraform-provider-talos/commit/e2d04acbf10eb092effa60a1cbc0eb27325d4b19) docs: fix wrong resource reference\n</p>\n</details>\n\n### Dependency Changes\n\nThis release has no dependency changes\n\nPrevious release can be found at [v0.1.0-alpha.3](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.3)\n\n## [terraform-provider-talos 0.1.0-alpha.3](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.3) (2022-09-08)\n\nWelcome to the v0.1.0-alpha.3 release of terraform-provider-talos!  \n*This is a pre-release of terraform-provider-talos*\n\n\n\nPlease try out the release binaries and report any issues at\nhttps://github.com/siderolabs/terraform-provider-talos/issues.\n\n### Talos Provider\n\nThe Talos provider supports generating configs, applying them and bootstrap the nodes.\n\nResources supported:\n\n* `talos_machine_secrets`\n* `talos_client_configuration`\n* `talos_machine_configuration_controlplane`\n* `talos_machine_configuration_worker`\n* `talos_machine_configuration_apply`\n* `talos_machine_bootstrap`\n* `talos_cluster_kubeconfig`\n\nData sources supported:\n\n* `talos_client_configuration`\n* `talos_cluster_kubeconfig`\n\nData sources will always create a diff and might be removed in a future release.\n\n\n### Contributors\n\n* Andrew Rynhard\n* Andrey Smirnov\n* Dmitriy Matrenichev\n* Noel Georgi\n\n### Changes\n<details><summary>2 commits</summary>\n<p>\n\n* [`e29e302`](https://github.com/siderolabs/terraform-provider-talos/commit/e29e3028b0b5dc3c56757a7724d1400d4d98b3e8) chore: add release workflow\n* [`4ecfd4f`](https://github.com/siderolabs/terraform-provider-talos/commit/4ecfd4f52353495a8304b0530d85a73b757861c9) feat: add new resources\n</p>\n</details>\n\n### Changes from siderolabs/go-pointer\n<details><summary>2 commits</summary>\n<p>\n\n* [`71ccdf0`](https://github.com/siderolabs/go-pointer/commit/71ccdf0d65330596f4def36da37625e4f362f2a9) chore: implement main functionality\n* [`c1c3b23`](https://github.com/siderolabs/go-pointer/commit/c1c3b235d30cb0de97ed0645809f2b21af3b021e) Initial commit\n</p>\n</details>\n\n### Dependency Changes\n\n* **github.com/cosi-project/runtime**   v0.1.1 **_new_**\n* **github.com/siderolabs/go-pointer**  v1.0.0 **_new_**\n* **google.golang.org/grpc**            v1.48.0 **_new_**\n\nPrevious release can be found at [v0.1.0-alpha.2](https://github.com/siderolabs/terraform-provider-talos/releases/tag/v0.1.0-alpha.2)\n\n"
  },
  {
    "path": "LICENSE",
    "content": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\n    means each individual or legal entity that creates, contributes to\n    the creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n    means the combination of the Contributions of others (if any) used\n    by a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n    means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n    means Source Code Form to which the initial Contributor has attached\n    the notice in Exhibit A, the Executable Form of such Source Code\n    Form, and Modifications of such Source Code Form, in each case\n    including portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n    means\n\n    (a) that the initial Contributor has attached the notice described\n        in Exhibit B to the Covered Software; or\n\n    (b) that the Covered Software was made available under the terms of\n        version 1.1 or earlier of the License, but not also under the\n        terms of a Secondary License.\n\n1.6. \"Executable Form\"\n    means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n    means a work that combines Covered Software with other material, in\n    a separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n    means this document.\n\n1.9. \"Licensable\"\n    means having the right to grant, to the maximum extent possible,\n    whether at the time of the initial grant or subsequently, any and\n    all of the rights conveyed by this License.\n\n1.10. \"Modifications\"\n    means any of the following:\n\n    (a) any file in Source Code Form that results from an addition to,\n        deletion from, or modification of the contents of Covered\n        Software; or\n\n    (b) any new file in Source Code Form that contains any Covered\n        Software.\n\n1.11. \"Patent Claims\" of a Contributor\n    means any patent claim(s), including without limitation, method,\n    process, and apparatus claims, in any patent Licensable by such\n    Contributor that would be infringed, but for the grant of the\n    License, by the making, using, selling, offering for sale, having\n    made, import, or transfer of either its Contributions or its\n    Contributor Version.\n\n1.12. \"Secondary License\"\n    means either the GNU General Public License, Version 2.0, the GNU\n    Lesser General Public License, Version 2.1, the GNU Affero General\n    Public License, Version 3.0, or any later versions of those\n    licenses.\n\n1.13. \"Source Code Form\"\n    means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n    means an individual or a legal entity exercising rights under this\n    License. For legal entities, \"You\" includes any entity that\n    controls, is controlled by, or is under common control with You. For\n    purposes of this definition, \"control\" means (a) the power, direct\n    or indirect, to cause the direction or management of such entity,\n    whether by contract or otherwise, or (b) ownership of more than\n    fifty percent (50%) of the outstanding shares or beneficial\n    ownership of such entity.\n\n2. License Grants and Conditions\n--------------------------------\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than patent or trademark)\n    Licensable by such Contributor to use, reproduce, make available,\n    modify, display, perform, distribute, and otherwise exploit its\n    Contributions, either on an unmodified basis, with Modifications, or\n    as part of a Larger Work; and\n\n(b) under Patent Claims of such Contributor to make, use, sell, offer\n    for sale, have made, import, and otherwise transfer either its\n    Contributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\n(a) for any code that a Contributor has removed from Covered Software;\n    or\n\n(b) for infringements caused by: (i) Your and any other third party's\n    modifications of Covered Software, or (ii) the combination of its\n    Contributions with other software (except as part of its Contributor\n    Version); or\n\n(c) under Patent Claims infringed by Covered Software in the absence of\n    its Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights\nto grant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted\nin Section 2.1.\n\n3. Responsibilities\n-------------------\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\n(a) such Covered Software must also be made available in Source Code\n    Form, as described in Section 3.1, and You must inform recipients of\n    the Executable Form how they can obtain a copy of such Source Code\n    Form by reasonable means in a timely manner, at a charge no more\n    than the cost of distribution to the recipient; and\n\n(b) You may distribute such Executable Form under the terms of this\n    License, or sublicense it under different terms, provided that the\n    license for the Executable Form does not attempt to limit or alter\n    the recipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty,\nor limitations of liability) contained within the Source Code Form of\nthe Covered Software, except that You may alter any license notices to\nthe extent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n---------------------------------------------------\n\nIf it is impossible for You to comply with any of the terms of this\nLicense with respect to some or all of the Covered Software due to\nstatute, judicial order, or regulation then You must: (a) comply with\nthe terms of this License to the maximum extent possible; and (b)\ndescribe the limitations and the code they affect. Such description must\nbe placed in a text file included with all distributions of the Covered\nSoftware under this License. Except to the extent prohibited by statute\nor regulation, such description must be sufficiently detailed for a\nrecipient of ordinary skill to be able to understand it.\n\n5. Termination\n--------------\n\n5.1. The rights granted under this License will terminate automatically\nif You fail to comply with any of its terms. However, if You become\ncompliant, then the rights granted under this License from a particular\nContributor are reinstated (a) provisionally, unless and until such\nContributor explicitly and finally terminates Your grants, and (b) on an\nongoing basis, if such Contributor fails to notify You of the\nnon-compliance by some reasonable means prior to 60 days after You have\ncome back into compliance. Moreover, Your grants from a particular\nContributor are reinstated on an ongoing basis if such Contributor\nnotifies You of the non-compliance by some reasonable means, this is the\nfirst time You have received notice of non-compliance with this License\nfrom such Contributor, and You become compliant prior to 30 days after\nYour receipt of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all\nend user license agreements (excluding distributors and resellers) which\nhave been validly granted by You or Your distributors under this License\nprior to termination shall survive termination.\n\n************************************************************************\n*                                                                      *\n*  6. Disclaimer of Warranty                                           *\n*  -------------------------                                           *\n*                                                                      *\n*  Covered Software is provided under this License on an \"as is\"       *\n*  basis, without warranty of any kind, either expressed, implied, or  *\n*  statutory, including, without limitation, warranties that the       *\n*  Covered Software is free of defects, merchantable, fit for a        *\n*  particular purpose or non-infringing. The entire risk as to the     *\n*  quality and performance of the Covered Software is with You.        *\n*  Should any Covered Software prove defective in any respect, You     *\n*  (not any Contributor) assume the cost of any necessary servicing,   *\n*  repair, or correction. This disclaimer of warranty constitutes an   *\n*  essential part of this License. No use of any Covered Software is   *\n*  authorized under this License except under this disclaimer.         *\n*                                                                      *\n************************************************************************\n\n************************************************************************\n*                                                                      *\n*  7. Limitation of Liability                                          *\n*  --------------------------                                          *\n*                                                                      *\n*  Under no circumstances and under no legal theory, whether tort      *\n*  (including negligence), contract, or otherwise, shall any           *\n*  Contributor, or anyone who distributes Covered Software as          *\n*  permitted above, be liable to You for any direct, indirect,         *\n*  special, incidental, or consequential damages of any character      *\n*  including, without limitation, damages for lost profits, loss of    *\n*  goodwill, work stoppage, computer failure or malfunction, or any    *\n*  and all other commercial damages or losses, even if such party      *\n*  shall have been informed of the possibility of such damages. This   *\n*  limitation of liability shall not apply to liability for death or   *\n*  personal injury resulting from such party's negligence to the       *\n*  extent applicable law prohibits such limitation. Some               *\n*  jurisdictions do not allow the exclusion or limitation of           *\n*  incidental or consequential damages, so this exclusion and          *\n*  limitation may not apply to You.                                    *\n*                                                                      *\n************************************************************************\n\n8. Litigation\n-------------\n\nAny litigation relating to this License may be brought only in the\ncourts of a jurisdiction where the defendant maintains its principal\nplace of business and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions.\nNothing in this Section shall prevent a party's ability to bring\ncross-claims or counter-claims.\n\n9. Miscellaneous\n----------------\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides\nthat the language of a contract shall be construed against the drafter\nshall not be used to construe this License against a Contributor.\n\n10. Versions of the License\n---------------------------\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses\n\nIf You choose to distribute Source Code Form that is Incompatible With\nSecondary Licenses under the terms of this version of the License, the\nnotice described in Exhibit B of this License must be attached.\n\nExhibit A - Source Code Form License Notice\n-------------------------------------------\n\n  This Source Code Form is subject to the terms of the Mozilla Public\n  License, v. 2.0. If a copy of the MPL was not distributed with this\n  file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular\nfile, then You may include the notice in a location (such as a LICENSE\nfile in a relevant directory) where a recipient would be likely to look\nfor such a notice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n---------------------------------------------------------\n\n  This Source Code Form is \"Incompatible With Secondary Licenses\", as\n  defined by the Mozilla Public License, v. 2.0.\n"
  },
  {
    "path": "Makefile",
    "content": "TAG ?= $(shell git describe --tag --always --dirty)\nARTIFACTS ?= _out\n\nifneq ($(origin TESTS), undefined)\n\tRUNARGS = -run='$(TESTS)'\nendif\n\nifneq ($(origin CI), undefined)\n\tRUNARGS += -parallel=3\n\tRUNARGS += -timeout=40m\n\tRUNARGS += -exec=\"sudo -E\"\nendif\n\n.PHONY: generate\ngenerate:\n\tgo generate ./pkg/talos\n\tgo generate\n\n.PHONY: testacc\ntestacc:\n\t# TF_CLI_CONFIG_FILE is set here to avoid using the user's .terraformrc file. Ref: https://github.com/hashicorp/terraform-plugin-sdk/issues/1171\n\tTF_CLI_CONFIG_FILE=\"thisfiledoesnotexist\" TF_ACC=1 go test -v -failfast -cover $(RUNARGS) ./...\n\n.PHONY: check-dirty\ncheck-dirty: generate ## Verifies that source tree is not dirty\n\t@if test -n \"`git status --porcelain`\"; then echo \"Source tree is dirty\"; git status; exit 1 ; fi\n\nbuild-debug:\n\tgo build -gcflags='all=-N -l'\n\ninstall:\n\tgo install .\n\n$(ARTIFACTS):\n\tmkdir -p $(ARTIFACTS)\n\nrelease-notes: $(ARTIFACTS)\n\t@ARTIFACTS=$(ARTIFACTS) ./hack/release.sh $@ $(ARTIFACTS)/RELEASE_NOTES.md $(TAG)\n\ngo-vulncheck:\n\tgo tool -modfile tools/go.mod golang.org/x/vuln/cmd/govulncheck ./...\n\nsbom: $(ARTIFACTS)\n\tSYFT_FORMAT_PRETTY=1 SYFT_FORMAT_SPDX_JSON_DETERMINISTIC_UUID=1 go tool -modfile tools/go.mod github.com/anchore/syft/cmd/syft dir:. -o spdx-json > $(ARTIFACTS)/sbom.spdx.json\n\tSYFT_FORMAT_PRETTY=1 SYFT_FORMAT_SPDX_JSON_DETERMINISTIC_UUID=1 go tool -modfile tools/go.mod github.com/anchore/syft/cmd/syft dir:. -o cyclonedx-json > $(ARTIFACTS)/sbom.cyclonedx.json\n"
  },
  {
    "path": "README.md",
    "content": "# terraform-provider-talos\n\n## Debugging\n\nIn a bash shell, build a debug version of this provider binary:\n\n```bash\nmake build-debug\n```\n\nIn Visual Studio Code, [start the provider in a debug session](https://developer.hashicorp.com/terraform/plugin/debugging#starting-a-provider-in-debug-mode).\n\nIn a new bash shell, go into your terraform project directory, and run\nterraform with `TF_REATTACH_PROVIDERS` set to the value printed in the VSCode debug windows.\n"
  },
  {
    "path": "docs/data-sources/client_configuration.md",
    "content": "---\n# generated by https://github.com/hashicorp/terraform-plugin-docs\npage_title: \"talos_client_configuration Data Source - talos\"\nsubcategory: \"\"\ndescription: |-\n  Generate client configuration for a Talos cluster\n---\n\n# talos_client_configuration (Data Source)\n\nGenerate client configuration for a Talos cluster\n\n## Example Usage\n\n```terraform\nresource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_client_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n  nodes                = [\"10.5.0.2\"]\n}\n```\n\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `client_configuration` (Attributes) The client configuration data (see [below for nested schema](#nestedatt--client_configuration))\n- `cluster_name` (String) The name of the cluster in the generated config\n\n### Optional\n\n- `endpoints` (List of String) endpoints to set in the generated config\n- `nodes` (List of String) nodes to set in the generated config\n\n### Read-Only\n\n- `id` (String) The ID of this resource\n- `talos_config` (String, Sensitive) The generated client configuration\n\n<a id=\"nestedatt--client_configuration\"></a>\n### Nested Schema for `client_configuration`\n\nRequired:\n\n- `ca_certificate` (String) The client CA certificate\n- `client_certificate` (String) The client certificate\n- `client_key` (String, Sensitive) The client key\n"
  },
  {
    "path": "docs/data-sources/cluster_health.md",
    "content": "---\n# generated by https://github.com/hashicorp/terraform-plugin-docs\npage_title: \"talos_cluster_health Data Source - talos\"\nsubcategory: \"\"\ndescription: |-\n  Waits for the Talos cluster to be healthy. Can be used as a dependency before running other operations on the cluster.\n---\n\n# talos_cluster_health (Data Source)\n\nWaits for the Talos cluster to be healthy. Can be used as a dependency before running other operations on the cluster.\n\n\n\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `client_configuration` (Attributes) The client configuration data (see [below for nested schema](#nestedatt--client_configuration))\n- `control_plane_nodes` (List of String) List of control plane nodes to check for health.\n- `endpoints` (List of String) endpoints to use for the health check client. Use at least one control plane endpoint.\n\n### Optional\n\n- `skip_kubernetes_checks` (Boolean) Skip Kubernetes component checks, this is useful to check if the nodes has finished booting up and kubelet is running. Default is false.\n- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))\n- `worker_nodes` (List of String) List of worker nodes to check for health.\n\n### Read-Only\n\n- `id` (String) The ID of this resource.\n\n<a id=\"nestedatt--client_configuration\"></a>\n### Nested Schema for `client_configuration`\n\nRequired:\n\n- `ca_certificate` (String) The client CA certificate\n- `client_certificate` (String) The client certificate\n- `client_key` (String, Sensitive) The client key\n\n\n<a id=\"nestedatt--timeouts\"></a>\n### Nested Schema for `timeouts`\n\nOptional:\n\n- `read` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as \"30s\" or \"2h45m\". Valid time units are \"s\" (seconds), \"m\" (minutes), \"h\" (hours). Read operations occur during any refresh or planning operation when refresh is enabled.\n"
  },
  {
    "path": "docs/data-sources/cluster_kubeconfig.md",
    "content": "---\n# generated by https://github.com/hashicorp/terraform-plugin-docs\npage_title: \"talos_cluster_kubeconfig Data Source - talos\"\nsubcategory: \"\"\ndescription: |-\n  Retrieves the kubeconfig for a Talos cluster\n---\n\n# talos_cluster_kubeconfig (Data Source)\n\nRetrieves the kubeconfig for a Talos cluster\n\n## Example Usage\n\n```terraform\nresource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  machine_type     = \"controlplane\"\n  cluster_endpoint = \"https://cluster.local:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\ndata \"talos_client_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n  nodes                = [\"10.5.0.2\"]\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.2\"\n  config_patches = [\n    yamlencode({\n      machine = {\n        install = {\n          disk = \"/dev/sdd\"\n        }\n      }\n    })\n  ]\n}\n\nresource \"talos_machine_bootstrap\" \"this\" {\n  depends_on = [\n    talos_machine_configuration_apply.this\n  ]\n  node                 = \"10.5.0.2\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n}\n\n\ndata \"talos_cluster_kubeconfig\" \"this\" {\n  depends_on = [\n    talos_machine_bootstrap.this\n  ]\n  client_configuration = talos_machine_secrets.this.client_configuration\n  node                 = \"10.5.0.2\"\n}\n```\n\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `client_configuration` (Attributes) The client configuration data (see [below for nested schema](#nestedatt--client_configuration))\n- `node` (String) controlplane node to retrieve the kubeconfig from\n\n### Optional\n\n- `endpoint` (String) endpoint to use for the talosclient. If not set, the node value will be used\n- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))\n- `wait` (Boolean, Deprecated) Wait for the kubernetes api to be available\n\n### Read-Only\n\n- `id` (String) The ID of this resource.\n- `kubeconfig_raw` (String, Sensitive) The raw kubeconfig\n- `kubernetes_client_configuration` (Attributes) The kubernetes client configuration (see [below for nested schema](#nestedatt--kubernetes_client_configuration))\n\n<a id=\"nestedatt--client_configuration\"></a>\n### Nested Schema for `client_configuration`\n\nRequired:\n\n- `ca_certificate` (String) The client CA certificate\n- `client_certificate` (String) The client certificate\n- `client_key` (String, Sensitive) The client key\n\n\n<a id=\"nestedatt--timeouts\"></a>\n### Nested Schema for `timeouts`\n\nOptional:\n\n- `read` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as \"30s\" or \"2h45m\". Valid time units are \"s\" (seconds), \"m\" (minutes), \"h\" (hours). Read operations occur during any refresh or planning operation when refresh is enabled.\n\n\n<a id=\"nestedatt--kubernetes_client_configuration\"></a>\n### Nested Schema for `kubernetes_client_configuration`\n\nRead-Only:\n\n- `ca_certificate` (String) The kubernetes CA certificate\n- `client_certificate` (String) The kubernetes client certificate\n- `client_key` (String, Sensitive) The kubernetes client key\n- `host` (String) The kubernetes host\n"
  },
  {
    "path": "docs/data-sources/image_factory_extensions_versions.md",
    "content": "---\n# generated by https://github.com/hashicorp/terraform-plugin-docs\npage_title: \"talos_image_factory_extensions_versions Data Source - talos\"\nsubcategory: \"\"\ndescription: |-\n  The image factory extensions versions data source provides a list of available extensions for a specific talos version from the image factory.\n---\n\n# talos_image_factory_extensions_versions (Data Source)\n\nThe image factory extensions versions data source provides a list of available extensions for a specific talos version from the image factory.\n\n## Example Usage\n\n```terraform\nprovider \"talos\" {}\n\ndata \"talos_image_factory_extensions_versions\" \"this\" {\n  # get the latest talos version\n  talos_version = \"v1.7.5\"\n  filters = {\n    names = [\n      \"amdgpu\",\n      \"tailscale\",\n    ]\n  }\n}\n```\n\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `talos_version` (String) The talos version to get extensions for.\n\n### Optional\n\n- `exact_filters` (Attributes) The filter to apply to the extensions list. (see [below for nested schema](#nestedatt--exact_filters))\n- `filters` (Attributes) The filter to apply to the extensions list. (see [below for nested schema](#nestedatt--filters))\n\n### Read-Only\n\n- `extensions_info` (List of Object) The list of available extensions for the specified talos version. (see [below for nested schema](#nestedatt--extensions_info))\n- `id` (String) The ID of this resource.\n\n<a id=\"nestedatt--exact_filters\"></a>\n### Nested Schema for `exact_filters`\n\nOptional:\n\n- `names` (List of String) The exact name match of the extension to filter by.\n\n\n<a id=\"nestedatt--filters\"></a>\n### Nested Schema for `filters`\n\nOptional:\n\n- `names` (List of String) The name of the extension to filter by.\n\n\n<a id=\"nestedatt--extensions_info\"></a>\n### Nested Schema for `extensions_info`\n\nRead-Only:\n\n- `author` (String)\n- `description` (String)\n- `digest` (String)\n- `name` (String)\n- `ref` (String)\n"
  },
  {
    "path": "docs/data-sources/image_factory_overlays_versions.md",
    "content": "---\n# generated by https://github.com/hashicorp/terraform-plugin-docs\npage_title: \"talos_image_factory_overlays_versions Data Source - talos\"\nsubcategory: \"\"\ndescription: |-\n  The image factory overlays versions data source provides a list of available overlays for a specific talos version from the image factory.\n---\n\n# talos_image_factory_overlays_versions (Data Source)\n\nThe image factory overlays versions data source provides a list of available overlays for a specific talos version from the image factory.\n\n## Example Usage\n\n```terraform\nprovider \"talos\" {}\n\ndata \"talos_image_factory_overlays_versions\" \"this\" {\n  # get the latest talos version\n  talos_version = \"v1.7.5\"\n  filters = {\n    name = \"rock4cplus\"\n  }\n}\n```\n\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `talos_version` (String) The talos version to get overlays for.\n\n### Optional\n\n- `filters` (Attributes) The filter to apply to the overlays list. (see [below for nested schema](#nestedatt--filters))\n\n### Read-Only\n\n- `id` (String) The ID of this resource.\n- `overlays_info` (List of Object) The list of available extensions for the specified talos version. (see [below for nested schema](#nestedatt--overlays_info))\n\n<a id=\"nestedatt--filters\"></a>\n### Nested Schema for `filters`\n\nOptional:\n\n- `name` (String) The name of the overlay to filter by.\n\n\n<a id=\"nestedatt--overlays_info\"></a>\n### Nested Schema for `overlays_info`\n\nRead-Only:\n\n- `digest` (String)\n- `image` (String)\n- `name` (String)\n- `ref` (String)\n"
  },
  {
    "path": "docs/data-sources/image_factory_urls.md",
    "content": "---\n# generated by https://github.com/hashicorp/terraform-plugin-docs\npage_title: \"talos_image_factory_urls Data Source - talos\"\nsubcategory: \"\"\ndescription: |-\n  Generates URLs for different assets supported by the Talos image factory.\n---\n\n# talos_image_factory_urls (Data Source)\n\nGenerates URLs for different assets supported by the Talos image factory.\n\n## Example Usage\n\n```terraform\ndata \"talos_image_factory_urls\" \"this\" {\n  talos_version = \"v1.7.5\"\n  schematic_id  = \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"\n  platform      = \"metal\"\n}\n\noutput \"installer_image\" {\n  value = data.talos_image_factory_urls.this.urls.installer\n}\n```\n\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `schematic_id` (String) The schematic ID for which the URLs are generated.\n- `talos_version` (String) The Talos version for which the URLs are generated.\n\n### Optional\n\n- `architecture` (String) The platform architecture for which the URLs are generated. Defaults to amd64.\n- `platform` (String) The platform for which the URLs are generated.\n\n\t#### Metal\n\n\t\t- metal\n\n    #### Cloud Platforms\n        - aws\n        - gcp\n        - equinixMetal\n        - azure\n        - digital-ocean\n        - nocloud\n        - openstack\n        - vmware\n        - akamai\n        - cloudstack\n        - hcloud\n        - oracle\n        - upcloud\n        - vultr\n        - exoscale\n        - opennebula\n        - scaleway\n- `sbc` (String) The SBC's (Single Board Copmuters) for which the url are generated.\n\n    #### Single Board Computers\n        - rpi_5\n        - rpi_generic\n        - revpi_generic\n        - bananapi_m64\n        - nanopi_r4s\n        - nanopi_r5s\n        - jetson_nano\n        - libretech_all_h3_cc_h5\n        - orangepi_r1_plus_lts\n        - pine64\n        - rock64\n        - rock4cplus\n        - rock4se\n        - rock5a\n        - rock5b\n        - rockpi_4\n        - rockpi_4c\n        - helios64\n        - turingrk1\n        - orangepi-5\n        - orangepi-5-plus\n        - rockpro64\n        - odroid-m1\n        - radxa-zero-3e\n        - rock3b\n        - orangepi-5-max\n        - rock5t\n        - friendlyelec-cm3588-nas\n        - rock5b-plus\n\n### Read-Only\n\n- `id` (String) The ID of this resource.\n- `urls` (Attributes) The URLs for different assets supported by the Talos image factory. If the URL is not available for a specific asset, it will be an empty string. (see [below for nested schema](#nestedatt--urls))\n\n<a id=\"nestedatt--urls\"></a>\n### Nested Schema for `urls`\n\nRead-Only:\n\n- `disk_image` (String) The URL for the disk image.\n- `disk_image_secureboot` (String) The URL for the disk image with secure boot.\n- `initramfs` (String) The URL for the initramfs image.\n- `installer` (String) The URL for the installer image.\n- `installer_secureboot` (String) The URL for the installer image with secure boot.\n- `iso` (String) The URL for the ISO image.\n- `iso_secureboot` (String) The URL for the ISO image with secure boot.\n- `kernel` (String) The URL for the kernel image.\n- `kernel_command_line` (String) The URL for the kernel command line.\n- `pxe` (String) The URL for the PXE image.\n- `uki` (String) The URL for the UKI image.\n"
  },
  {
    "path": "docs/data-sources/image_factory_versions.md",
    "content": "---\n# generated by https://github.com/hashicorp/terraform-plugin-docs\npage_title: \"talos_image_factory_versions Data Source - talos\"\nsubcategory: \"\"\ndescription: |-\n  The image factory versions data source provides a list of available talos versions from the image factory.\n---\n\n# talos_image_factory_versions (Data Source)\n\nThe image factory versions data source provides a list of available talos versions from the image factory.\n\n## Example Usage\n\n```terraform\nprovider \"talos\" {}\n\ndata \"talos_image_factory_versions\" \"this\" {}\n\noutput \"latest\" {\n  value = element(data.talos_image_factory_versions.this.talos_versions, length(data.talos_image_factory_versions.this.talos_versions) - 1)\n}\n```\n\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Optional\n\n- `filters` (Attributes) The filter to apply to the overlays list. (see [below for nested schema](#nestedatt--filters))\n\n### Read-Only\n\n- `id` (String) The ID of this resource.\n- `talos_versions` (List of String) The list of available talos versions.\n\n<a id=\"nestedatt--filters\"></a>\n### Nested Schema for `filters`\n\nOptional:\n\n- `stable_versions_only` (Boolean) If set to true, only stable versions will be returned. If set to false, all versions will be returned.\n"
  },
  {
    "path": "docs/data-sources/machine_configuration.md",
    "content": "---\npage_title: \"talos_machine_configuration Data Source - talos\"\nsubcategory: \"\"\ndescription: |-\n  Generate a machine configuration for a node type\n---\n\n# talos_machine_configuration (Data Source)\n\nGenerate a machine configuration for a node type\n\n-> **Note:** It is recommended to set the optional `talos_version` attribute. Otherwise when using a new version of the provider with a new major version of the Talos SDK, new machineconfig features will be enabled by default which could cause unexpected behavior.\n\n## Example Usage\n\n```terraform\nresource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  machine_type     = \"controlplane\"\n  cluster_endpoint = \"https://cluster.local:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n```\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `cluster_endpoint` (String) The endpoint of the talos kubernetes cluster\n- `cluster_name` (String) The name of the talos kubernetes cluster\n- `machine_secrets` (Attributes) The secrets for the talos cluster (see [below for nested schema](#nestedatt--machine_secrets))\n- `machine_type` (String) The type of machine to generate the configuration for\n\n### Optional\n\n- `config_patches` (List of String) The list of config patches to apply to the generated configuration\n- `docs` (Boolean) Whether to generate documentation for the generated configuration. Defaults to false\n- `examples` (Boolean) Whether to generate examples for the generated configuration. Defaults to false\n- `kubernetes_version` (String) The version of kubernetes to use\n- `talos_version` (String) The Talos version contract used to generate the machine configuration. This does not control the installed Talos version. Use `config_patches` to set `machine.install.image` to the desired value. Example values: `v1.12`, `v1.12.1`, `1.12`, `1.12.1`\n\n### Read-Only\n\n- `id` (String) The ID of this resource.\n- `machine_configuration` (String, Sensitive) The generated machine configuration\n\n<a id=\"nestedatt--machine_secrets\"></a>\n### Nested Schema for `machine_secrets`\n\nRequired:\n\n- `certs` (Attributes) The certs for the talos kubernetes cluster (see [below for nested schema](#nestedatt--machine_secrets--certs))\n- `cluster` (Attributes) The cluster secrets (see [below for nested schema](#nestedatt--machine_secrets--cluster))\n- `secrets` (Attributes) The secrets for the talos kubernetes cluster (see [below for nested schema](#nestedatt--machine_secrets--secrets))\n- `trustdinfo` (Attributes) The trustd info for the talos kubernetes cluster (see [below for nested schema](#nestedatt--machine_secrets--trustdinfo))\n\n<a id=\"nestedatt--machine_secrets--certs\"></a>\n### Nested Schema for `machine_secrets.certs`\n\nRequired:\n\n- `etcd` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--etcd))\n- `k8s` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s))\n- `k8s_aggregator` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s_aggregator))\n- `k8s_serviceaccount` (Attributes) (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s_serviceaccount))\n- `os` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--os))\n\n<a id=\"nestedatt--machine_secrets--certs--etcd\"></a>\n### Nested Schema for `machine_secrets.certs.etcd`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s\"></a>\n### Nested Schema for `machine_secrets.certs.k8s`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s_aggregator\"></a>\n### Nested Schema for `machine_secrets.certs.k8s_aggregator`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s_serviceaccount\"></a>\n### Nested Schema for `machine_secrets.certs.k8s_serviceaccount`\n\nRequired:\n\n- `key` (String, Sensitive) The key for the k8s service account\n\n\n<a id=\"nestedatt--machine_secrets--certs--os\"></a>\n### Nested Schema for `machine_secrets.certs.os`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n\n<a id=\"nestedatt--machine_secrets--cluster\"></a>\n### Nested Schema for `machine_secrets.cluster`\n\nRequired:\n\n- `id` (String) The cluster id\n- `secret` (String, Sensitive) The cluster secret\n\n\n<a id=\"nestedatt--machine_secrets--secrets\"></a>\n### Nested Schema for `machine_secrets.secrets`\n\nRequired:\n\n- `bootstrap_token` (String, Sensitive) The bootstrap token for the talos kubernetes cluster\n- `secretbox_encryption_secret` (String, Sensitive) The secretbox encryption secret for the talos kubernetes cluster\n\nOptional:\n\n- `aescbc_encryption_secret` (String, Sensitive) The aescbc encryption secret for the talos kubernetes cluster\n\n\n<a id=\"nestedatt--machine_secrets--trustdinfo\"></a>\n### Nested Schema for `machine_secrets.trustdinfo`\n\nRequired:\n\n- `token` (String, Sensitive) The trustd token for the talos kubernetes cluster\n"
  },
  {
    "path": "docs/data-sources/machine_disks.md",
    "content": "---\npage_title: \"talos_machine_disks Data Source - talos\"\nsubcategory: \"\"\ndescription: |-\n  Generate a machine configuration for a node type\n---\n\n# talos_machine_disks (Data Source)\n\nGenerate a machine configuration for a node type\n\n-> **Note:** Since Talos natively supports `.machine.install.diskSelector`, the `talos_machine_disks` data source maybe just used to query disk information that could be used elsewhere. It's recommended to use `machine.install.diskSelector` in Talos machine configuration.\n\n## Example Usage\n\n```terraform\nresource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_disks\" \"this\" {\n  client_configuration = talos_machine_secrets.this.client_configuration\n  node                 = \"10.5.0.2\"\n  selector             = \"disk.size > 6u * GB\"\n}\n\n# for example, this could be used to pass in a list of disks to rook-ceph\noutput \"nvme_disks\" {\n  value = data.talos_machine_disks.this.disks.*.name\n}\n```\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `client_configuration` (Attributes) The client configuration data (see [below for nested schema](#nestedatt--client_configuration))\n- `node` (String) controlplane node to retrieve the kubeconfig from\n\n### Optional\n\n- `endpoint` (String) endpoint to use for the talosclient. If not set, the node value will be used\n- `selector` (String) The CEL expression to filter the disks.\nIf not set, all disks will be returned.\nSee [CEL documentation](https://www.talos.dev/latest/talos-guides/configuration/disk-management/#disk-selector).\n- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))\n\n### Read-Only\n\n- `disks` (Attributes List) The disks that match the filters (see [below for nested schema](#nestedatt--disks))\n- `id` (String) The generated ID of this resource\n\n<a id=\"nestedatt--client_configuration\"></a>\n### Nested Schema for `client_configuration`\n\nRequired:\n\n- `ca_certificate` (String) The client CA certificate\n- `client_certificate` (String) The client certificate\n- `client_key` (String, Sensitive) The client key\n\n\n<a id=\"nestedatt--timeouts\"></a>\n### Nested Schema for `timeouts`\n\nOptional:\n\n- `read` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as \"30s\" or \"2h45m\". Valid time units are \"s\" (seconds), \"m\" (minutes), \"h\" (hours). Read operations occur during any refresh or planning operation when refresh is enabled.\n\n\n<a id=\"nestedatt--disks\"></a>\n### Nested Schema for `disks`\n\nRead-Only:\n\n- `bus_path` (String)\n- `cdrom` (Boolean)\n- `dev_path` (String)\n- `io_size` (Number)\n- `modalias` (String)\n- `model` (String)\n- `pretty_size` (String)\n- `readonly` (Boolean)\n- `rotational` (Boolean)\n- `secondary_disks` (List of String)\n- `sector_size` (Number)\n- `serial` (String)\n- `size` (Number)\n- `sub_system` (String)\n- `symlinks` (List of String)\n- `transport` (String)\n- `uuid` (String)\n- `wwid` (String)\n"
  },
  {
    "path": "docs/ephemeral-resources/client_configuration.md",
    "content": "---\n# generated by https://github.com/hashicorp/terraform-plugin-docs\npage_title: \"talos_client_configuration Ephemeral Resource - talos\"\nsubcategory: \"\"\ndescription: |-\n  Generate client configuration for a Talos cluster from machine secrets. This is an ephemeral resource that does not persist secrets in Terraform state. The admin client certificate is generated with pinned timestamps so talos_config is byte-identical on every open as long as machine_secrets and not_before are unchanged.\n---\n\n# talos_client_configuration (Ephemeral Resource)\n\nGenerate client configuration for a Talos cluster from machine secrets. This is an ephemeral resource that does not persist secrets in Terraform state. The admin client certificate is generated with pinned timestamps so talos_config is byte-identical on every open as long as machine_secrets and not_before are unchanged.\n\n\n\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `cluster_name` (String) The name of the cluster in the generated config\n- `machine_secrets` (Attributes) The secrets for the talos cluster (see [below for nested schema](#nestedatt--machine_secrets))\n\n### Optional\n\n- `crt_ttl` (String) The lifetime of the generated admin client certificate as a Go duration string (e.g. \"8760h\" for 1 year, \"87600h\" for 10 years). Defaults to \"87600h\" (10 years). Only used when not_before is set; when not_before is omitted the cert uses the OS CA's NotAfter directly.\n- `endpoints` (List of String) endpoints to set in the generated config\n- `nodes` (List of String) nodes to set in the generated config\n- `not_before` (String) RFC3339 timestamp to use as the NotBefore field of the generated admin client certificate. When set, the certificate validity starts at this time and ends at not_before + crt_ttl. Persist this value in a terraform_data resource so it is stable across plans and the generated talos_config is byte-identical on every open. When omitted, the certificate uses the OS CA's own NotBefore/NotAfter timestamps.\n\n### Read-Only\n\n- `client_configuration` (Attributes, Sensitive) The generated client configuration data (see [below for nested schema](#nestedatt--client_configuration))\n- `talos_config` (String, Sensitive) The generated client configuration\n\n<a id=\"nestedatt--machine_secrets\"></a>\n### Nested Schema for `machine_secrets`\n\nRequired:\n\n- `certs` (Attributes) The certs for the talos kubernetes cluster (see [below for nested schema](#nestedatt--machine_secrets--certs))\n- `cluster` (Attributes) The cluster secrets (see [below for nested schema](#nestedatt--machine_secrets--cluster))\n- `secrets` (Attributes) The secrets for the talos kubernetes cluster (see [below for nested schema](#nestedatt--machine_secrets--secrets))\n- `trustdinfo` (Attributes) The trustd info for the talos kubernetes cluster (see [below for nested schema](#nestedatt--machine_secrets--trustdinfo))\n\n<a id=\"nestedatt--machine_secrets--certs\"></a>\n### Nested Schema for `machine_secrets.certs`\n\nRequired:\n\n- `etcd` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--etcd))\n- `k8s` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s))\n- `k8s_aggregator` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s_aggregator))\n- `k8s_serviceaccount` (Attributes) (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s_serviceaccount))\n- `os` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--os))\n\n<a id=\"nestedatt--machine_secrets--certs--etcd\"></a>\n### Nested Schema for `machine_secrets.certs.etcd`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s\"></a>\n### Nested Schema for `machine_secrets.certs.k8s`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s_aggregator\"></a>\n### Nested Schema for `machine_secrets.certs.k8s_aggregator`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s_serviceaccount\"></a>\n### Nested Schema for `machine_secrets.certs.k8s_serviceaccount`\n\nRequired:\n\n- `key` (String, Sensitive) The key for the k8s service account\n\n\n<a id=\"nestedatt--machine_secrets--certs--os\"></a>\n### Nested Schema for `machine_secrets.certs.os`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n\n<a id=\"nestedatt--machine_secrets--cluster\"></a>\n### Nested Schema for `machine_secrets.cluster`\n\nRequired:\n\n- `id` (String) The cluster id\n- `secret` (String, Sensitive) The cluster secret\n\n\n<a id=\"nestedatt--machine_secrets--secrets\"></a>\n### Nested Schema for `machine_secrets.secrets`\n\nRequired:\n\n- `bootstrap_token` (String, Sensitive) The bootstrap token for the talos kubernetes cluster\n- `secretbox_encryption_secret` (String, Sensitive) The secretbox encryption secret for the talos kubernetes cluster\n\nOptional:\n\n- `aescbc_encryption_secret` (String, Sensitive) The aescbc encryption secret for the talos kubernetes cluster\n\n\n<a id=\"nestedatt--machine_secrets--trustdinfo\"></a>\n### Nested Schema for `machine_secrets.trustdinfo`\n\nRequired:\n\n- `token` (String, Sensitive) The trustd token for the talos kubernetes cluster\n\n\n\n<a id=\"nestedatt--client_configuration\"></a>\n### Nested Schema for `client_configuration`\n\nRead-Only:\n\n- `ca_certificate` (String) The client CA certificate\n- `client_certificate` (String) The client certificate\n- `client_key` (String, Sensitive) The client key\n"
  },
  {
    "path": "docs/ephemeral-resources/cluster_health.md",
    "content": "---\n# generated by https://github.com/hashicorp/terraform-plugin-docs\npage_title: \"talos_cluster_health Ephemeral Resource - talos\"\nsubcategory: \"\"\ndescription: |-\n  Checks the health of a Talos cluster. This is an ephemeral resource that does not persist secrets in Terraform state.\n---\n\n# talos_cluster_health (Ephemeral Resource)\n\nChecks the health of a Talos cluster. This is an ephemeral resource that does not persist secrets in Terraform state.\n\n\n\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `client_configuration` (Attributes) The client configuration data (see [below for nested schema](#nestedatt--client_configuration))\n- `control_plane_nodes` (List of String) List of control plane nodes to check for health.\n- `endpoints` (List of String) endpoints to use for the health check client. Use at least one control plane endpoint.\n\n### Optional\n\n- `skip_kubernetes_checks` (Boolean) Skip Kubernetes component checks, this is useful to check if the nodes has finished booting up and kubelet is running. Default is false.\n- `timeout` (String) Timeout for the health check. Defaults to 10m. Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'.\n- `worker_nodes` (List of String) List of worker nodes to check for health.\n\n<a id=\"nestedatt--client_configuration\"></a>\n### Nested Schema for `client_configuration`\n\nRequired:\n\n- `ca_certificate` (String) The client CA certificate\n- `client_certificate` (String) The client certificate\n- `client_key` (String, Sensitive) The client key\n"
  },
  {
    "path": "docs/ephemeral-resources/cluster_kubeconfig.md",
    "content": "---\n# generated by https://github.com/hashicorp/terraform-plugin-docs\npage_title: \"talos_cluster_kubeconfig Ephemeral Resource - talos\"\nsubcategory: \"\"\ndescription: |-\n  Generate a kubeconfig for a Talos cluster from machine secrets. This is an ephemeral resource that does not persist secrets in Terraform state. The admin client certificate is generated with pinned timestamps so kubeconfig_raw is byte-identical on every open as long as machine_secrets and not_before are unchanged.\n---\n\n# talos_cluster_kubeconfig (Ephemeral Resource)\n\nGenerate a kubeconfig for a Talos cluster from machine secrets. This is an ephemeral resource that does not persist secrets in Terraform state. The admin client certificate is generated with pinned timestamps so kubeconfig_raw is byte-identical on every open as long as machine_secrets and not_before are unchanged.\n\n## Example Usage\n\n```terraform\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n  endpoint        = \"https://10.5.0.2:6443\"\n}\n\n# Recommended pattern for stable kubeconfig when storing in a secret manager:\n# Persist not_before in terraform_data so the admin cert timestamps are fixed\n# across plan invocations and kubeconfig_raw is byte-identical on every open.\nresource \"terraform_data\" \"kubeconfig_nbf\" {\n  input = plantimestamp()\n  lifecycle {\n    ignore_changes = [input]\n  }\n}\n\nephemeral \"talos_cluster_kubeconfig\" \"stable\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n  endpoint        = \"https://10.5.0.2:6443\"\n  not_before      = terraform_data.kubeconfig_nbf.output\n  crt_ttl         = \"87600h\"\n}\n```\n\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `cluster_name` (String) The name of the cluster; embedded in the kubeconfig context and cluster names\n- `endpoint` (String) The Kubernetes API server URL to embed in the kubeconfig (e.g. https://1.2.3.4:6443)\n- `machine_secrets` (Attributes) The secrets for the talos cluster (see [below for nested schema](#nestedatt--machine_secrets))\n\n### Optional\n\n- `crt_ttl` (String) The lifetime of the generated admin client certificate as a Go duration string (e.g. \"8760h\" for 1 year, \"87600h\" for 10 years). Defaults to \"87600h\" (10 years). Only used when not_before is set; when not_before is omitted the cert uses the K8s CA's NotAfter directly.\n- `not_before` (String) RFC3339 timestamp to use as the NotBefore field of the generated admin client certificate. When set, the certificate validity starts at this time and ends at not_before + crt_ttl. Persist this value in a terraform_data resource so it is stable across plans and the generated kubeconfig_raw is byte-identical on every open. When omitted, the certificate uses the K8s CA's own NotBefore/NotAfter timestamps.\n\n### Read-Only\n\n- `kubeconfig_raw` (String, Sensitive) The raw kubeconfig\n- `kubernetes_client_configuration` (Attributes) The kubernetes client configuration (see [below for nested schema](#nestedatt--kubernetes_client_configuration))\n\n<a id=\"nestedatt--machine_secrets\"></a>\n### Nested Schema for `machine_secrets`\n\nRequired:\n\n- `certs` (Attributes) The certs for the talos kubernetes cluster (see [below for nested schema](#nestedatt--machine_secrets--certs))\n- `cluster` (Attributes) The cluster secrets (see [below for nested schema](#nestedatt--machine_secrets--cluster))\n- `secrets` (Attributes) The secrets for the talos kubernetes cluster (see [below for nested schema](#nestedatt--machine_secrets--secrets))\n- `trustdinfo` (Attributes) The trustd info for the talos kubernetes cluster (see [below for nested schema](#nestedatt--machine_secrets--trustdinfo))\n\n<a id=\"nestedatt--machine_secrets--certs\"></a>\n### Nested Schema for `machine_secrets.certs`\n\nRequired:\n\n- `etcd` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--etcd))\n- `k8s` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s))\n- `k8s_aggregator` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s_aggregator))\n- `k8s_serviceaccount` (Attributes) (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s_serviceaccount))\n- `os` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--os))\n\n<a id=\"nestedatt--machine_secrets--certs--etcd\"></a>\n### Nested Schema for `machine_secrets.certs.etcd`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s\"></a>\n### Nested Schema for `machine_secrets.certs.k8s`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s_aggregator\"></a>\n### Nested Schema for `machine_secrets.certs.k8s_aggregator`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s_serviceaccount\"></a>\n### Nested Schema for `machine_secrets.certs.k8s_serviceaccount`\n\nRequired:\n\n- `key` (String, Sensitive) The key for the k8s service account\n\n\n<a id=\"nestedatt--machine_secrets--certs--os\"></a>\n### Nested Schema for `machine_secrets.certs.os`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n\n<a id=\"nestedatt--machine_secrets--cluster\"></a>\n### Nested Schema for `machine_secrets.cluster`\n\nRequired:\n\n- `id` (String) The cluster id\n- `secret` (String, Sensitive) The cluster secret\n\n\n<a id=\"nestedatt--machine_secrets--secrets\"></a>\n### Nested Schema for `machine_secrets.secrets`\n\nRequired:\n\n- `bootstrap_token` (String, Sensitive) The bootstrap token for the talos kubernetes cluster\n- `secretbox_encryption_secret` (String, Sensitive) The secretbox encryption secret for the talos kubernetes cluster\n\nOptional:\n\n- `aescbc_encryption_secret` (String, Sensitive) The aescbc encryption secret for the talos kubernetes cluster\n\n\n<a id=\"nestedatt--machine_secrets--trustdinfo\"></a>\n### Nested Schema for `machine_secrets.trustdinfo`\n\nRequired:\n\n- `token` (String, Sensitive) The trustd token for the talos kubernetes cluster\n\n\n\n<a id=\"nestedatt--kubernetes_client_configuration\"></a>\n### Nested Schema for `kubernetes_client_configuration`\n\nRead-Only:\n\n- `ca_certificate` (String) The kubernetes CA certificate\n- `client_certificate` (String) The kubernetes client certificate\n- `client_key` (String, Sensitive) The kubernetes client key\n- `host` (String) The kubernetes host\n"
  },
  {
    "path": "docs/ephemeral-resources/machine_configuration.md",
    "content": "---\npage_title: \"talos_machine_configuration Ephemeral Resource - talos\"\nsubcategory: \"\"\ndescription: |-\n  Generate a machine configuration for a node type. This is an ephemeral resource that does not persist secrets in Terraform state.\n---\n\n# talos_machine_configuration (Ephemeral Resource)\n\nGenerate a machine configuration for a node type. This is an ephemeral resource that does not persist secrets in Terraform state.\n\n-> **Note:** It is recommended to set the optional `talos_version` attribute. Otherwise when using a new version of the provider with a new major version of the Talos SDK, new machineconfig features will be enabled by default which could cause unexpected behavior.\n\n\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `cluster_endpoint` (String) The endpoint of the talos kubernetes cluster\n- `cluster_name` (String) The name of the talos kubernetes cluster\n- `machine_secrets` (Attributes) The secrets for the talos cluster (see [below for nested schema](#nestedatt--machine_secrets))\n- `machine_type` (String) The type of machine to generate the configuration for\n\n### Optional\n\n- `config_patches` (List of String) The list of config patches to apply to the generated configuration\n- `docs` (Boolean) Whether to generate documentation for the generated configuration. Defaults to false\n- `examples` (Boolean) Whether to generate examples for the generated configuration. Defaults to false\n- `kubernetes_version` (String) The version of kubernetes to use\n- `talos_version` (String) The Talos version contract used to generate the machine configuration. This does not control the installed Talos version. Use `config_patches` to set `machine.install.image` to the desired value. Example values: `v1.12`, `v1.12.1`, `1.12`, `1.12.1`\n\n### Read-Only\n\n- `machine_configuration` (String, Sensitive) The generated machine configuration\n\n<a id=\"nestedatt--machine_secrets\"></a>\n### Nested Schema for `machine_secrets`\n\nRequired:\n\n- `certs` (Attributes) The certs for the talos kubernetes cluster (see [below for nested schema](#nestedatt--machine_secrets--certs))\n- `cluster` (Attributes) The cluster secrets (see [below for nested schema](#nestedatt--machine_secrets--cluster))\n- `secrets` (Attributes) The secrets for the talos kubernetes cluster (see [below for nested schema](#nestedatt--machine_secrets--secrets))\n- `trustdinfo` (Attributes) The trustd info for the talos kubernetes cluster (see [below for nested schema](#nestedatt--machine_secrets--trustdinfo))\n\n<a id=\"nestedatt--machine_secrets--certs\"></a>\n### Nested Schema for `machine_secrets.certs`\n\nRequired:\n\n- `etcd` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--etcd))\n- `k8s` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s))\n- `k8s_aggregator` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s_aggregator))\n- `k8s_serviceaccount` (Attributes) (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s_serviceaccount))\n- `os` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--os))\n\n<a id=\"nestedatt--machine_secrets--certs--etcd\"></a>\n### Nested Schema for `machine_secrets.certs.etcd`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s\"></a>\n### Nested Schema for `machine_secrets.certs.k8s`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s_aggregator\"></a>\n### Nested Schema for `machine_secrets.certs.k8s_aggregator`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s_serviceaccount\"></a>\n### Nested Schema for `machine_secrets.certs.k8s_serviceaccount`\n\nRequired:\n\n- `key` (String, Sensitive) The key for the k8s service account\n\n\n<a id=\"nestedatt--machine_secrets--certs--os\"></a>\n### Nested Schema for `machine_secrets.certs.os`\n\nRequired:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n\n<a id=\"nestedatt--machine_secrets--cluster\"></a>\n### Nested Schema for `machine_secrets.cluster`\n\nRequired:\n\n- `id` (String) The cluster id\n- `secret` (String, Sensitive) The cluster secret\n\n\n<a id=\"nestedatt--machine_secrets--secrets\"></a>\n### Nested Schema for `machine_secrets.secrets`\n\nRequired:\n\n- `bootstrap_token` (String, Sensitive) The bootstrap token for the talos kubernetes cluster\n- `secretbox_encryption_secret` (String, Sensitive) The secretbox encryption secret for the talos kubernetes cluster\n\nOptional:\n\n- `aescbc_encryption_secret` (String, Sensitive) The aescbc encryption secret for the talos kubernetes cluster\n\n\n<a id=\"nestedatt--machine_secrets--trustdinfo\"></a>\n### Nested Schema for `machine_secrets.trustdinfo`\n\nRequired:\n\n- `token` (String, Sensitive) The trustd token for the talos kubernetes cluster\n"
  },
  {
    "path": "docs/ephemeral-resources/machine_secrets.md",
    "content": "---\n# generated by https://github.com/hashicorp/terraform-plugin-docs\npage_title: \"talos_machine_secrets Ephemeral Resource - talos\"\nsubcategory: \"\"\ndescription: |-\n  Generate machine secrets for Talos cluster. This is an ephemeral resource that does not persist secrets in Terraform state.\n---\n\n# talos_machine_secrets (Ephemeral Resource)\n\nGenerate machine secrets for Talos cluster. This is an ephemeral resource that does not persist secrets in Terraform state.\n\n\n\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Optional\n\n- `talos_version` (String) The Talos version contract used to generate the secrets. Example values: `v1.12`, `v1.12.1`, `1.12`, `1.12.1`\n\n### Read-Only\n\n- `client_configuration` (Attributes) The generated client configuration data (see [below for nested schema](#nestedatt--client_configuration))\n- `machine_secrets` (Attributes) The secrets for the talos cluster (see [below for nested schema](#nestedatt--machine_secrets))\n\n<a id=\"nestedatt--client_configuration\"></a>\n### Nested Schema for `client_configuration`\n\nRead-Only:\n\n- `ca_certificate` (String) The client CA certificate\n- `client_certificate` (String) The client certificate\n- `client_key` (String, Sensitive) The client key\n\n\n<a id=\"nestedatt--machine_secrets\"></a>\n### Nested Schema for `machine_secrets`\n\nRead-Only:\n\n- `certs` (Attributes) (see [below for nested schema](#nestedatt--machine_secrets--certs))\n- `cluster` (Attributes) The cluster secrets (see [below for nested schema](#nestedatt--machine_secrets--cluster))\n- `secrets` (Attributes) kubernetes cluster secrets (see [below for nested schema](#nestedatt--machine_secrets--secrets))\n- `trustdinfo` (Attributes) trustd secrets (see [below for nested schema](#nestedatt--machine_secrets--trustdinfo))\n\n<a id=\"nestedatt--machine_secrets--certs\"></a>\n### Nested Schema for `machine_secrets.certs`\n\nRead-Only:\n\n- `etcd` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--etcd))\n- `k8s` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s))\n- `k8s_aggregator` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s_aggregator))\n- `k8s_serviceaccount` (Attributes) The service account secrets (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s_serviceaccount))\n- `os` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--os))\n\n<a id=\"nestedatt--machine_secrets--certs--etcd\"></a>\n### Nested Schema for `machine_secrets.certs.etcd`\n\nRead-Only:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s\"></a>\n### Nested Schema for `machine_secrets.certs.k8s`\n\nRead-Only:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s_aggregator\"></a>\n### Nested Schema for `machine_secrets.certs.k8s_aggregator`\n\nRead-Only:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s_serviceaccount\"></a>\n### Nested Schema for `machine_secrets.certs.k8s_serviceaccount`\n\nRead-Only:\n\n- `key` (String, Sensitive) The service account key\n\n\n<a id=\"nestedatt--machine_secrets--certs--os\"></a>\n### Nested Schema for `machine_secrets.certs.os`\n\nRead-Only:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n\n<a id=\"nestedatt--machine_secrets--cluster\"></a>\n### Nested Schema for `machine_secrets.cluster`\n\nRead-Only:\n\n- `id` (String) The cluster ID\n- `secret` (String, Sensitive) The cluster secret\n\n\n<a id=\"nestedatt--machine_secrets--secrets\"></a>\n### Nested Schema for `machine_secrets.secrets`\n\nRead-Only:\n\n- `aescbc_encryption_secret` (String, Sensitive) The AES-CBC encryption secret\n- `bootstrap_token` (String, Sensitive) The bootstrap token\n- `secretbox_encryption_secret` (String, Sensitive) The secretbox encryption secret\n\n\n<a id=\"nestedatt--machine_secrets--trustdinfo\"></a>\n### Nested Schema for `machine_secrets.trustdinfo`\n\nRead-Only:\n\n- `token` (String, Sensitive) The trustd token\n"
  },
  {
    "path": "docs/guides/using_ephemeral_resources.md",
    "content": "---\npage_title: \"Using Ephemeral Resources - talos Provider\"\nsubcategory: \"\"\ndescription: |-\n  Learn how to use ephemeral resources in the Talos provider to prevent secrets from being stored in Terraform state\n---\n\n# Using Ephemeral Resources in the Talos Provider\n\nEphemeral resources are Terraform resources that are essentially temporary. They allow you to access and use data in your configurations without that data being stored in Terraform state. This is particularly important for sensitive data like machine secrets, certificates, and kubeconfig files.\n\nEphemeral resources are available in Terraform v1.10 and later. For more information, see the [official HashiCorp documentation for Ephemeral Resources](https://developer.hashicorp.com/terraform/language/resources/ephemeral).\n\n## Available Ephemeral Resources\n\nThe Talos provider includes five ephemeral resources:\n\n- [`talos_machine_secrets`](https://registry.terraform.io/providers/siderolabs/talos/latest/docs/ephemeral-resources/machine_secrets) - Generate machine secrets without storing them in state\n- [`talos_machine_configuration`](https://registry.terraform.io/providers/siderolabs/talos/latest/docs/ephemeral-resources/machine_configuration) - Generate machine configuration without storing secrets in state\n- [`talos_client_configuration`](https://registry.terraform.io/providers/siderolabs/talos/latest/docs/ephemeral-resources/client_configuration) - Generate client configuration (talosconfig) without storing credentials in state\n- [`talos_cluster_kubeconfig`](https://registry.terraform.io/providers/siderolabs/talos/latest/docs/ephemeral-resources/cluster_kubeconfig) - Retrieve kubeconfig without storing credentials in state\n- [`talos_cluster_health`](https://registry.terraform.io/providers/siderolabs/talos/latest/docs/ephemeral-resources/cluster_health) - Check cluster health without storing credentials in state\n\nThese complement the existing data sources and resources, allowing you to avoid storing credentials and secret values in your Terraform state.\n\n## Why Use Ephemeral Resources?\n\n**Security Benefits:**\n\n- Secrets never written to Terraform state files\n- Reduces risk of credential exposure through state files\n- Complies with security policies requiring secret-free state\n\n**When to Use:**\n\n- Generating Talos machine secrets\n- Creating machine configurations with sensitive data\n- Retrieving kubeconfig files\n- Any workflow where secrets shouldn't persist in state\n\n## Critical: Machine Secrets Persistence\n\n**IMPORTANT**: Do not use `ephemeral \"talos_machine_secrets\"` without also storing them in a secret manager. Generating ephemeral machine secrets without persistence would create **new secrets on every Terraform run**, causing:\n\n- Unpredictable changes to dependent resources\n- Need to reconfigure all cluster nodes\n- Loss of access to the cluster with previous credentials\n- Non-deterministic infrastructure state\n\n### Correct Pattern: Secret Manager Integration\n\nMachine secrets should be:\n\n1. Generated once and stored in a secret manager (Vault, AWS Secrets Manager, etc.)\n2. Retrieved ephemerally from the secret manager when needed\n3. Used to generate machine configurations deterministically\n\nThis ensures:\n\n- Secrets remain stable across Terraform runs\n- No secrets stored in Terraform state\n- Deterministic, reproducible infrastructure\n- Compliance with security policies\n\n## Using Ephemeral Resources with Write-Only Attributes\n\nEphemeral resources are a source of ephemeral data, and they can be referenced in your configuration just like the attributes of resources and data sources. However, a field that references an ephemeral resource must be capable of handling ephemeral data.\n\nThe Talos provider includes write-only attributes that accept ephemeral values:\n\n- `machine_configuration_input_wo` - Write-only alternative to `machine_configuration_input` on `talos_machine_configuration_apply` resource (requires Terraform 1.11+)\n\n## Example: Using Vault for Secret Persistence\n\nThis example demonstrates the correct pattern for managing Talos machine secrets with Vault. Both secret generation and retrieval can coexist in the same configuration:\n\n```terraform\nterraform {\n  required_version = \">= 1.11\"\n  required_providers {\n    talos = {\n      source  = \"siderolabs/talos\"\n      version = \"~> 0.11\"\n    }\n    vault = {\n      source  = \"hashicorp/vault\"\n      version = \"~> 5.0\"\n    }\n  }\n}\n\n# Step 1: Generate and store secrets in Vault\n# The ephemeral resource generates secrets only when needed (first run)\n# After initial creation, this won't be evaluated because data_json_wo_version is hardcoded\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nresource \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = \"secret\"\n  name  = \"talos-cluster-${var.cluster_name}\"\n\n  # Write-only attributes prevent secrets from being stored in Terraform state\n  data_json_wo = jsonencode({\n    machine_secrets      = ephemeral.talos_machine_secrets.this.machine_secrets\n    client_configuration = ephemeral.talos_machine_secrets.this.client_configuration\n  })\n  # Hardcoded version prevents unnecessary refreshes after initial creation\n  data_json_wo_version = 1\n}\n\n# Step 2: Retrieve secrets ephemerally from Vault\n# This runs on every terraform operation but values are never stored in state\n# Referencing the resource attributes creates implicit dependency on the secret\nephemeral \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = vault_kv_secret_v2.talos_secrets.mount\n  name  = vault_kv_secret_v2.talos_secrets.name\n}\n\nlocals {\n  # Decode the secret data\n  talos_data = jsondecode(ephemeral.vault_kv_secret_v2.talos_secrets.data_json)\n}\n\n# Step 3: Generate machine configuration using retrieved secrets\nephemeral \"talos_machine_configuration\" \"controlplane\" {\n  cluster_name     = var.cluster_name\n  cluster_endpoint = var.cluster_endpoint\n  machine_type     = \"controlplane\"\n  machine_secrets  = local.talos_data.machine_secrets\n}\n\n# Step 4: Apply configuration using write-only input\nresource \"talos_machine_configuration_apply\" \"controlplane\" {\n  client_configuration_wo        = local.talos_data.client_configuration\n  machine_configuration_input_wo = ephemeral.talos_machine_configuration.controlplane.machine_configuration\n  node                           = var.controlplane_node\n\n  # Note: machine_configuration computed attribute will be null in state\n  # This is expected behavior for secret-free operation\n}\n```\n\n**Secret-Free Operation:**\n\nWhen using write-only attributes (`_wo` variants), the provider ensures zero secrets leak into state:\n\n- **Write-only inputs** (`client_configuration_wo`, `machine_configuration_input_wo`): Never stored in state\n- **Computed outputs** (`machine_configuration`): Automatically set to null in state when using write-only inputs\n\nThe provider computes the machine configuration internally during apply operations without persisting it. This provides complete secret-free operation while maintaining full functionality.\n\n**How This Works:**\n\n1. **First Run**:\n   - Secrets are generated ephemerally\n   - Stored in Vault with version 1\n   - Retrieved from Vault for immediate use\n   - All in a single `terraform apply` (Terraform handles the ordering automatically)\n\n2. **Subsequent Runs**:\n   - The `vault_kv_secret_v2` resource doesn't need updates (version is hardcoded)\n   - The `ephemeral \"talos_machine_secrets\"` isn't evaluated (no dependent resources need it)\n   - Secrets are retrieved ephemerally from Vault for use in configuration\n\n**Key Benefits:**\n\n- Works in a single run on first apply\n- Both blocks coexist permanently in your configuration\n- Terraform handles all dependencies automatically\n- No secrets stored in Terraform state\n\n### Alternative Pattern: External Secret Generation\n\nIf you prefer to manage secret generation outside Terraform:\n\n```bash\n# Generate secrets manually using talosctl\ntalosctl gen secrets -o secrets.yaml\n\n# Store in Vault using vault CLI\nvault kv put secret/talos-cluster-prod \\\n  machine_secrets=\"$(yq -o=json '.machine_secrets' secrets.yaml)\" \\\n  client_configuration=\"$(yq -o=json '.client_configuration' secrets.yaml)\"\n```\n\nThen your Terraform configuration only needs the retrieval part:\n\n```terraform\nephemeral \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = \"secret\"\n  name  = \"talos-cluster-prod\"\n}\n\nlocals {\n  talos_data = jsondecode(ephemeral.vault_kv_secret_v2.talos_secrets.data_json)\n}\n\nephemeral \"talos_machine_configuration\" \"controlplane\" {\n  cluster_name     = \"prod-cluster\"\n  cluster_endpoint = \"https://10.5.0.2:6443\"\n  machine_type     = \"controlplane\"\n  machine_secrets  = local.talos_data.machine_secrets\n}\n```\n\n## Example: Generating Kubeconfig Ephemerally from Machine Secrets\n\nThis example shows how to generate a kubeconfig ephemerally from machine secrets stored in Vault.\nThe kubeconfig is generated locally from the Kubernetes CA key — no live cluster required.\n\n### Simple usage (CA-pinned timestamps)\n\nWhen `not_before` is omitted, the admin certificate validity window is taken from the K8s CA's\nown timestamps (set once when the cluster was created). The output is byte-identical on every\nplan as long as `machine_secrets` does not change.\n\n```terraform\n# Retrieve stored secrets from Vault\nephemeral \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = \"secret\"\n  name  = \"talos-cluster-prod\"\n}\n\nlocals {\n  talos_data = jsondecode(ephemeral.vault_kv_secret_v2.talos_secrets.data_json)\n}\n\n# Generate kubeconfig without storing in state\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n  cluster_name    = \"prod-cluster\"\n  machine_secrets = local.talos_data.machine_secrets\n  endpoint        = \"https://10.5.0.2:6443\"\n}\n\n# Output the kubeconfig (marked as ephemeral)\noutput \"kubeconfig\" {\n  value     = ephemeral.talos_cluster_kubeconfig.this.kubeconfig_raw\n  sensitive = true\n  ephemeral = true\n}\n```\n\n### Recommended pattern for Vault-backed workflows (explicit `not_before`)\n\nWhen storing `kubeconfig_raw` in a Vault KV secret (or any resource that detects byte changes),\nuse a `terraform_data` resource to persist a stable `not_before` timestamp in Terraform state.\nThis pins the admin certificate validity window so `kubeconfig_raw` is byte-identical across\nall plan invocations — no `ignore_changes` or `data_json_wo_version` bumps required until you\nexplicitly rotate the certificate.\n\n```terraform\n# Persist the admin cert NotBefore timestamp in regular Terraform state.\n# Use ignore_changes so it is set once and never updated automatically.\n# To rotate the cert: taint this resource and re-apply.\nresource \"terraform_data\" \"kubeconfig_nbf\" {\n  input = plantimestamp()\n  lifecycle {\n    ignore_changes = [input]\n  }\n}\n\n# Generate kubeconfig with pinned timestamps\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n  cluster_name    = \"prod-cluster\"\n  machine_secrets = local.talos_data.machine_secrets\n  endpoint        = \"https://10.5.0.2:6443\"\n  not_before      = terraform_data.kubeconfig_nbf.output\n  crt_ttl         = \"87600h\"\n}\n\n# Store kubeconfig in Vault — kubeconfig_raw is stable so this resource\n# only updates when machine_secrets or not_before change.\nresource \"vault_kv_secret_v2\" \"kubeconfig\" {\n  mount = \"secret\"\n  name  = \"kubeconfig-prod-cluster\"\n\n  data_json_wo         = jsonencode({ kubeconfig = ephemeral.talos_cluster_kubeconfig.this.kubeconfig_raw })\n  data_json_wo_version = 1\n}\n```\n\n**Certificate rotation**: taint `terraform_data.kubeconfig_nbf` to force a new `not_before`,\nwhich produces a new cert and triggers a `data_json_wo_version` bump on the Vault secret.\n\n**Note**: The kubeconfig is generated locally from the machine secrets and does not require\na running cluster.\n\n## Alternative Secret Managers\n\nWhile the examples above use HashiCorp Vault, you can use any secret manager that supports:\n\n- Storing secrets via Terraform resources\n- Retrieving secrets via ephemeral resources\n\n### AWS Secrets Manager Example\n\n```terraform\n# Store secrets in AWS Secrets Manager\nresource \"aws_secretsmanager_secret\" \"talos_secrets\" {\n  name = \"talos-cluster-${var.cluster_name}\"\n}\n\nresource \"aws_secretsmanager_secret_version\" \"talos_secrets\" {\n  secret_id = aws_secretsmanager_secret.talos_secrets.id\n  secret_string = jsonencode({\n    machine_secrets      = talos_machine_secrets.this.machine_secrets\n    client_configuration = talos_machine_secrets.this.client_configuration\n  })\n}\n\n# Note: AWS provider doesn't yet have ephemeral resources for Secrets Manager\n# You would use a data source, which still stores in state\n# Watch for AWS provider updates adding ephemeral support\n```\n\n### Azure Key Vault Example\n\n```terraform\n# Store secrets in Azure Key Vault\nresource \"azurerm_key_vault_secret\" \"talos_secrets\" {\n  name         = \"talos-cluster-${var.cluster_name}\"\n  value        = jsonencode({\n    machine_secrets      = talos_machine_secrets.this.machine_secrets\n    client_configuration = talos_machine_secrets.this.client_configuration\n  })\n  key_vault_id = azurerm_key_vault.main.id\n}\n\n# Note: Azure provider doesn't yet have ephemeral resources for Key Vault\n# You would use a data source for now\n```\n\n## Important Considerations\n\n### Terraform Version Requirements\n\n- **Terraform 1.10+**: Supports ephemeral resources only (no write-only attributes)\n- **Terraform 1.11+**: Supports both ephemeral resources and write-only attributes\n- **OpenTofu 1.11+**: Supports both ephemeral resources and write-only attributes\n  - Note: OpenTofu 1.10 does NOT support ephemeral resources (they were introduced in 1.11)\n\n**For the examples in this guide**: Terraform 1.11+ or OpenTofu 1.11+ required (uses write-only attributes)\n\n### Compatibility with Existing Resources\n\nEphemeral resources complement existing data sources and resources:\n\n- **Data sources** (e.g., `data.talos_machine_configuration`) - Still work, but store output in state\n- **Ephemeral resources** (e.g., `ephemeral.talos_machine_configuration`) - Same functionality, no state storage\n\nYou can migrate existing configurations to ephemeral resources by:\n\n1. Changing `data \"talos_machine_configuration\"` to `ephemeral \"talos_machine_configuration\"`\n2. Updating references from `data.talos_machine_configuration.this` to `ephemeral.talos_machine_configuration.this`\n3. Using write-only attributes (e.g., `machine_configuration_input_wo`) where applicable\n\n## Migration Guide\n\n### From Data Source to Ephemeral Resource with Vault\n\n**Before (using data source):**\n\n```terraform\nresource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"my-cluster\"\n  cluster_endpoint = \"https://10.5.0.2:6443\"\n  machine_type     = \"controlplane\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.2\"\n}\n```\n\n**After (using ephemeral resources with Vault):**\n\nStep 1 - Store existing secrets in Vault (one-time migration):\n\n```terraform\n# Assuming you have existing talos_machine_secrets resource\nresource \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = \"secret\"\n  name  = \"talos-cluster-my-cluster\"\n\n  data_json_wo = jsonencode({\n    machine_secrets      = talos_machine_secrets.this.machine_secrets\n    client_configuration = talos_machine_secrets.this.client_configuration\n  })\n}\n```\n\nStep 2 - Use ephemeral resources to retrieve from Vault:\n\n```terraform\n# Retrieve secrets from Vault ephemerally\n# Reference the resource to create implicit dependency\nephemeral \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = vault_kv_secret_v2.talos_secrets.mount\n  name  = vault_kv_secret_v2.talos_secrets.name\n}\n\nlocals {\n  talos_data = jsondecode(ephemeral.vault_kv_secret_v2.talos_secrets.data_json)\n}\n\n# Generate configuration ephemerally\nephemeral \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"my-cluster\"\n  cluster_endpoint = \"https://10.5.0.2:6443\"\n  machine_type     = \"controlplane\"\n  machine_secrets  = local.talos_data.machine_secrets\n}\n\n# Apply configuration using write-only attribute\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration_wo        = local.talos_data.client_configuration\n  machine_configuration_input_wo = ephemeral.talos_machine_configuration.this.machine_configuration\n  node                           = \"10.5.0.2\"\n}\n```\n\nStep 3 - After verifying the migration works, remove the `talos_machine_secrets` resource from your state:\n\n```bash\nterraform state rm talos_machine_secrets.this\n```\n\n**Benefits:**\n\n- Machine secrets stored securely in Vault, not in Terraform state\n- Secrets remain stable across Terraform runs\n- Machine configuration never stored in state\n- Deterministic infrastructure state\n- Improved security and compliance\n"
  },
  {
    "path": "docs/guides/version-0.2-upgrade.html.md",
    "content": "---\npage_title: \"Terraform Talos Provider Version 0.2 Upgrade Guide\"\ndescription: |-\n  Terraform Talos Provider Version 0.2 Upgrade Guide\n---\n\n# Terraform Talos Provider Version 0.2 Upgrade Guide <!-- omit in toc -->\n\nVersion 0.2 of the Talos Terraform provider is a major release and include some breaking chages. This guide will walk you through the changes and how to upgrade your Terraform configuration.\n\n~> **NOTE:** Version 0.2 of the Talos Terraform provider drops support for the following resources:\n\n> * `talos_client_configuration`\n> * `talos_cluster_kubeconfig`\n> * `talos_machine_configuration_controlplane`\n> * `talos_machine_configuration_worker`\n\nThe following table lists the resources that have been removed and the new resources that replace them.\n\n| Removed Resource                           | Type     | New Resource                  | Type          |\n| ------------------------------------------ | -------- | ----------------------------- | ------------- |\n| `talos_client_configuration`               | Resource | `talos_client_configuration`  | Data Source   |\n| `talos_cluster_kubeconfig`                 | Resource | `talos_cluster_kubeconfig`    | Data Source   |\n| `talos_machine_configuration_controlplane` | Resource | `talos_machine_configuration` | Data Resource |\n| `talos_machine_configuration_worker`       | Resource | `talos_machine_configuration` | Data Resource |\n\n## Upgrade topics: <!-- omit in toc -->\n\n- [Upgrading `talos_client_configuration` resource](#upgrading-talos_client_configuration-resource)\n- [Upgrading `talos_cluster_kubeconfig` resource](#upgrading-talos_cluster_kubeconfig-resource)\n- [Upgrading `talos_machine_configuration_controlplane` resource](#upgrading-talos_machine_configuration_controlplane-resource)\n- [Upgrading `talos_machine_configuration_worker` resource](#upgrading-talos_machine_configuration_worker-resource)\n\n### Upgrading `talos_client_configuration` resource\n\nThe `talos_client_configuration` resource has been removed. The `talos_client_configuration` data source should be used instead.\n\nFor example if the following resource was used:\n\n```hcl\nresource \"talos_machine_secrets\" \"this\" {}\n\nresource \"talos_client_configuration\" \"talosconfig\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = talos_machine_secrets.this.machine_secrets\n}\n```\n\n`talos_client_configuration` resource should be first removed from the state:\n\n```bash\nterraform state rm talos_client_configuration.talosconfig\n```\n\nand the code should be updated to:\n\n```hcl\nresource \"talos_machine_secrets\" \"machine_secrets\" {}\n\ndata \"talos_client_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n}\n```\n\n### Upgrading `talos_cluster_kubeconfig` resource\n\nThe `talos_cluster_kubeconfig` resource has been removed. The `talos_cluster_kubeconfig` data source should be used instead.\n\nFor example if the following resource was used:\n\n```hcl\nresource \"talos_machine_secrets\" \"this\" {}\n\nresource \"talos_client_configuration\" \"this\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_cluster_kubeconfig\" \"kubeconfig\" {\n  talos_config = talos_client_configuration.this.talos_config\n  endpoint     = \"10.5.0.2\"\n  node         = \"10.5.0.2\"\n}\n```\n\n`talos_cluster_kubeconfig` resource should be first removed from the state:\n\n```bash\nterraform state rm talos_cluster_kubeconfig.kubeconfig\n```\n\nand the code should be updated to:\n\n```hcl\nresource \"talos_machine_secrets\" \"machine_secrets\" {}\n\ndata \"talos_cluster_kubeconfig\" \"this\" {\n  client_configuration = talos_machine_secrets.this.client_configuration\n  node                 = \"10.5.0.2\"\n}\n```\n\n### Upgrading `talos_machine_configuration_controlplane` resource\n\nThe `talos_machine_configuration_controlplane` resource has been removed. The `talos_machine_configuration` data source should be used instead.\n\nFor example if the following resource was used:\n\n```hcl\nresource \"talos_machine_secrets\" \"this\" {}\n\nresource \"talos_client_configuration\" \"this\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_controlplane\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  cluster_endpoint = \"https://10.5.0.2:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  talos_config          = talos_client_configuration.this.talos_config\n  machine_configuration = talos_machine_configuration_controlplane.this.machine_config\n  node                  = \"10.5.0.2\"\n  endpoint              = \"10.5.0.2\"\n}\n```\n\n`talos_machine_configuration_controlplane` resource should be first removed from the state:\n\n```bash\nterraform state rm talos_machine_configuration_controlplane.cp\n```\n\nand the code should be updated to:\n\n```hcl\nresource \"talos_machine_secrets\" \"machine_secrets\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  cluster_endpoint     = \"https://10.5.0.2:6443\"\n  machine_type         = \"controlplane\"\n  talos_version        = talos_machine_secrets.this.talos_version\n  machine_secrets      = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.2\"\n}\n```\n\n### Upgrading `talos_machine_configuration_worker` resource\n\nThe `talos_machine_configuration_worker` resource has been removed. The `talos_machine_configuration` data source should be used instead.\n\nFor example if the following resource was used:\n\n```hcl\nresource \"talos_machine_secrets\" \"this\" {}\n\nresource \"talos_client_configuration\" \"this\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_worker\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  cluster_endpoint = \"https://10.5.0.2:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  talos_config          = talos_client_configuration.this.talos_config\n  machine_configuration = talos_machine_configuration_worker.this.machine_config\n  node                  = \"10.5.0.3\"\n  endpoint              = \"10.5.0.3\"\n}\n```\n\n`talos_machine_configuration_worker` resource should be first removed from the state:\n\n```bash\nterraform state rm talos_machine_configuration_worker.worker\n```\n\nand the code should be updated to:\n\n```hcl\nresource \"talos_machine_secrets\" \"machine_secrets\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  cluster_endpoint     = \"https://10.5.0.2:6443\"\n  machine_type         = \"worker\"\n  talos_version        = talos_machine_secrets.this.talos_version\n  machine_secrets      = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.3\"\n}\n```\n"
  },
  {
    "path": "docs/index.md",
    "content": "---\npage_title: \"Provider: Talos\"\ndescription: |-\n  The Talos provider is used to manage a Talos cluster config generation and initial setup.\n---\n\n# Talos Provider\n\nTalos provider allows to generate configs for a Talos cluster and apply them to the nodes, bootstrap nodes, check cluster health, and retrieve `kubeconfig` and `talosconfig`.\n\nComplete usages for this provider across a variety of environments can be found [here](https://github.com/siderolabs/contrib/tree/main/examples/terraform).\n"
  },
  {
    "path": "docs/resources/cluster_kubeconfig.md",
    "content": "---\npage_title: \"talos_cluster_kubeconfig Resource - talos\"\nsubcategory: \"\"\ndescription: |-\n  Retrieves the kubeconfig for a Talos cluster\n---\n\n# talos_cluster_kubeconfig (Resource)\n\nRetrieves the kubeconfig for a Talos cluster\n\n## Example Usage\n\n```terraform\nresource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  machine_type     = \"controlplane\"\n  cluster_endpoint = \"https://cluster.local:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\ndata \"talos_client_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n  nodes                = [\"10.5.0.2\"]\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.2\"\n  config_patches = [\n    yamlencode({\n      machine = {\n        install = {\n          disk = \"/dev/sdd\"\n        }\n      }\n    })\n  ]\n}\n\nresource \"talos_machine_bootstrap\" \"this\" {\n  depends_on = [\n    talos_machine_configuration_apply.this\n  ]\n  node                 = \"10.5.0.2\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n}\n\n\nresource \"talos_cluster_kubeconfig\" \"this\" {\n  depends_on = [\n    talos_machine_bootstrap.this\n  ]\n  client_configuration = talos_machine_secrets.this.client_configuration\n  node                 = \"10.5.0.2\"\n}\n```\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `client_configuration` (Attributes) The client configuration data (see [below for nested schema](#nestedatt--client_configuration))\n- `node` (String) controlplane node to retrieve the kubeconfig from\n\n### Optional\n\n- `certificate_renewal_duration` (String) The duration in hours before the certificate is renewed, defaults to 720h. Must be a valid duration string\n- `endpoint` (String) endpoint to use for the talosclient. If not set, the node value will be used\n- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))\n\n### Read-Only\n\n- `id` (String) The ID of this resource.\n- `kubeconfig_raw` (String, Sensitive) The raw kubeconfig\n- `kubernetes_client_configuration` (Attributes) The kubernetes client configuration (see [below for nested schema](#nestedatt--kubernetes_client_configuration))\n\n<a id=\"nestedatt--client_configuration\"></a>\n### Nested Schema for `client_configuration`\n\nRequired:\n\n- `ca_certificate` (String) The client CA certificate\n- `client_certificate` (String) The client certificate\n- `client_key` (String, Sensitive) The client key\n\n\n<a id=\"nestedatt--timeouts\"></a>\n### Nested Schema for `timeouts`\n\nOptional:\n\n- `create` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as \"30s\" or \"2h45m\". Valid time units are \"s\" (seconds), \"m\" (minutes), \"h\" (hours).\n- `update` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as \"30s\" or \"2h45m\". Valid time units are \"s\" (seconds), \"m\" (minutes), \"h\" (hours).\n\n\n<a id=\"nestedatt--kubernetes_client_configuration\"></a>\n### Nested Schema for `kubernetes_client_configuration`\n\nRead-Only:\n\n- `ca_certificate` (String) The kubernetes CA certificate\n- `client_certificate` (String) The kubernetes client certificate\n- `client_key` (String, Sensitive) The kubernetes client key\n- `host` (String) The kubernetes host\n\n"
  },
  {
    "path": "docs/resources/image_factory_schematic.md",
    "content": "---\npage_title: \"talos_image_factory_schematic Resource - talos\"\nsubcategory: \"\"\ndescription: |-\n  The image factory schematic resource allows you to create a schematic for a Talos image.\n---\n\n# talos_image_factory_schematic (Resource)\n\nThe image factory schematic resource allows you to create a schematic for a Talos image.\n\n## Example Usage\n\n```terraform\nprovider \"talos\" {}\n\ndata \"talos_image_factory_extensions_versions\" \"this\" {\n  # get the latest talos version\n  talos_version = \"v1.7.5\"\n  filters = {\n    names = [\n      \"amdgpu\",\n      \"tailscale\",\n    ]\n  }\n}\n\nresource \"talos_image_factory_schematic\" \"this\" {\n  schematic = yamlencode(\n    {\n      customization = {\n        systemExtensions = {\n          officialExtensions = data.talos_image_factory_extensions_versions.this.extensions_info.*.name\n        }\n      }\n    }\n  )\n}\n\noutput \"schematic_id\" {\n  value = talos_image_factory_schematic.this.id\n}\n```\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Optional\n\n- `schematic` (String) The schematic yaml respresentation to generate the image.\n\nIf not set, a vanilla Talos image schematic will be generated.\n\n> Refer to [image-factory](https://github.com/siderolabs/image-factory?tab=readme-ov-file#post-schematics) for the schema.\n\n### Read-Only\n\n- `id` (String) The unique ID of the schematic, returned from Image Factory.\n\n"
  },
  {
    "path": "docs/resources/machine_bootstrap.md",
    "content": "---\npage_title: \"talos_machine_bootstrap Resource - talos\"\nsubcategory: \"\"\ndescription: |-\n  The machine bootstrap resource allows you to bootstrap a Talos node.\n---\n\n# talos_machine_bootstrap (Resource)\n\nThe machine bootstrap resource allows you to bootstrap a Talos node.\n\n## Example Usage\n\n```terraform\nresource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  machine_type     = \"controlplane\"\n  cluster_endpoint = \"https://cluster.local:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\ndata \"talos_client_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n  nodes                = [\"10.5.0.2\"]\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.2\"\n  config_patches = [\n    yamlencode({\n      machine = {\n        install = {\n          disk = \"/dev/sdd\"\n        }\n      }\n    })\n  ]\n}\n\nresource \"talos_machine_bootstrap\" \"this\" {\n  depends_on = [\n    talos_machine_configuration_apply.this\n  ]\n  node                 = \"10.5.0.2\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n}\n```\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `node` (String) The name of the node to bootstrap\n\n### Optional\n\n> **NOTE**: [Write-only arguments](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments) are supported in Terraform 1.11 and later.\n\n- `client_configuration` (Attributes) The client configuration data (see [below for nested schema](#nestedatt--client_configuration))\n- `client_configuration_wo` (Attributes, [Write-only](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments)) The client configuration data (write-only). Use this instead of client_configuration when using ephemeral resources. Requires Terraform 1.11+ (see [below for nested schema](#nestedatt--client_configuration_wo))\n- `endpoint` (String) The endpoint of the machine to bootstrap\n- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))\n\n### Read-Only\n\n- `id` (String) This is a unique identifier for the machine\n\n<a id=\"nestedatt--client_configuration\"></a>\n### Nested Schema for `client_configuration`\n\nRequired:\n\n- `ca_certificate` (String) The client CA certificate\n- `client_certificate` (String) The client certificate\n- `client_key` (String, Sensitive) The client key\n\n\n<a id=\"nestedatt--client_configuration_wo\"></a>\n### Nested Schema for `client_configuration_wo`\n\nRequired:\n\n- `ca_certificate` (String, [Write-only](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments)) The client CA certificate\n- `client_certificate` (String, [Write-only](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments)) The client certificate\n- `client_key` (String, Sensitive, [Write-only](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments)) The client key\n\n\n<a id=\"nestedatt--timeouts\"></a>\n### Nested Schema for `timeouts`\n\nOptional:\n\n- `create` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as \"30s\" or \"2h45m\". Valid time units are \"s\" (seconds), \"m\" (minutes), \"h\" (hours).\n## Import\n\nImport is supported using the following syntax:\n\n```terraform\n# machine bootstrap can be imported to let terraform know that the machine is already bootstrapped\nterraform import talos_machine_bootstrap.this <any id>\n```\n"
  },
  {
    "path": "docs/resources/machine_configuration_apply.md",
    "content": "---\npage_title: \"talos_machine_configuration_apply Resource - talos\"\nsubcategory: \"\"\ndescription: |-\n  The machine configuration apply resource allows to apply machine configuration to a node\n---\n\n# talos_machine_configuration_apply (Resource)\n\nThe machine configuration apply resource allows to apply machine configuration to a node\n\n## Example Usage\n\n```terraform\nresource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  machine_type     = \"controlplane\"\n  cluster_endpoint = \"https://cluster.local:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\ndata \"talos_client_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n  nodes                = [\"10.5.0.2\"]\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.2\"\n  config_patches = [\n    yamlencode({\n      machine = {\n        install = {\n          disk  = \"/dev/sdd\"\n          image = \"ghcr.io/siderolabs/installer:v1.12.6\"\n        }\n      }\n    })\n  ]\n}\n```\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Required\n\n- `node` (String) The name of the node to bootstrap\n\n### Optional\n\n> **NOTE**: [Write-only arguments](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments) are supported in Terraform 1.11 and later.\n\n- `apply_mode` (String) The mode of the apply operation. Use 'staged_if_needing_reboot' for automatic reboot prevention: performs a dry-run and uses 'staged' mode if reboot is needed, 'auto' otherwise\n- `client_configuration` (Attributes) The client configuration data (see [below for nested schema](#nestedatt--client_configuration))\n- `client_configuration_wo` (Attributes, [Write-only](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments)) The client configuration data (write-only). Use this instead of client_configuration when using ephemeral resources. Requires Terraform 1.11+ (see [below for nested schema](#nestedatt--client_configuration_wo))\n- `config_patches` (List of String) The list of config patches to apply\n- `endpoint` (String) The endpoint of the machine to bootstrap\n- `machine_configuration_input` (String, Sensitive) The machine configuration to apply\n- `machine_configuration_input_wo` (String, [Write-only](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments)) The machine configuration to apply (write-only). Use this instead of machine_configuration_input when using ephemeral resources. Requires Terraform 1.11+\n- `on_destroy` (Attributes) Actions to be taken on destroy, if *reset* is not set this is a no-op.\n\n> Note: Any changes to *on_destroy* block has to be applied first by running *terraform apply* first,\nthen a subsequent *terraform destroy* for the changes to take effect due to limitations in Terraform provider framework. (see [below for nested schema](#nestedatt--on_destroy))\n- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))\n\n### Read-Only\n\n- `id` (String) This is a unique identifier for the machine\n- `machine_configuration` (String, Sensitive) The generated machine configuration after applying patches\n- `machine_configuration_hash` (String) SHA256 hex digest of the rendered machine configuration (input plus patches). Persisted in state so that changes to machine_configuration_input_wo — which is write-only and itself invisible to state — still surface as plan diffs.\n- `resolved_apply_mode` (String) The actual apply mode used. When apply_mode is 'staged_if_needing_reboot', shows the resolved mode ('auto' or 'staged') based on dry-run analysis. Equals apply_mode for other modes.\n\n<a id=\"nestedatt--client_configuration\"></a>\n### Nested Schema for `client_configuration`\n\nRequired:\n\n- `ca_certificate` (String) The client CA certificate\n- `client_certificate` (String) The client certificate\n- `client_key` (String, Sensitive) The client key\n\n\n<a id=\"nestedatt--client_configuration_wo\"></a>\n### Nested Schema for `client_configuration_wo`\n\nRequired:\n\n- `ca_certificate` (String, [Write-only](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments)) The client CA certificate\n- `client_certificate` (String, [Write-only](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments)) The client certificate\n- `client_key` (String, Sensitive, [Write-only](https://developer.hashicorp.com/terraform/language/resources/ephemeral#write-only-arguments)) The client key\n\n\n<a id=\"nestedatt--on_destroy\"></a>\n### Nested Schema for `on_destroy`\n\nOptional:\n\n- `graceful` (Boolean) Graceful indicates whether node should leave etcd before the upgrade, it also enforces etcd checks before leaving. Default true\n- `reboot` (Boolean) Reboot indicates whether node should reboot or halt after resetting. Default false\n- `reset` (Boolean) Reset the machine to the initial state (STATE and EPHEMERAL will be wiped). Default false\n\n\n<a id=\"nestedatt--timeouts\"></a>\n### Nested Schema for `timeouts`\n\nOptional:\n\n- `create` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as \"30s\" or \"2h45m\". Valid time units are \"s\" (seconds), \"m\" (minutes), \"h\" (hours).\n- `delete` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as \"30s\" or \"2h45m\". Valid time units are \"s\" (seconds), \"m\" (minutes), \"h\" (hours). Setting a timeout for a Delete operation is only applicable if changes are saved into state before the destroy operation occurs.\n- `update` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as \"30s\" or \"2h45m\". Valid time units are \"s\" (seconds), \"m\" (minutes), \"h\" (hours).\n\n"
  },
  {
    "path": "docs/resources/machine_secrets.md",
    "content": "---\npage_title: \"talos_machine_secrets Resource - talos\"\nsubcategory: \"\"\ndescription: |-\n  Generate machine secrets for Talos cluster.\n---\n\n# talos_machine_secrets (Resource)\n\nGenerate machine secrets for Talos cluster.\n\n## Example Usage\n\n```terraform\nresource \"talos_machine_secrets\" \"machine_secrets\" {}\n```\n<!-- schema generated by tfplugindocs -->\n## Schema\n\n### Optional\n\n- `talos_version` (String) The Talos version contract used to generate the secrets. Example values: `v1.12`, `v1.12.1`, `1.12`, `1.12.1`\n\n### Read-Only\n\n- `client_configuration` (Attributes) The generated client configuration data (see [below for nested schema](#nestedatt--client_configuration))\n- `id` (String) The computed ID of the Talos cluster\n- `machine_secrets` (Attributes) The secrets for the talos cluster (see [below for nested schema](#nestedatt--machine_secrets))\n\n<a id=\"nestedatt--client_configuration\"></a>\n### Nested Schema for `client_configuration`\n\nRead-Only:\n\n- `ca_certificate` (String) The client CA certificate\n- `client_certificate` (String) The client certificate\n- `client_key` (String, Sensitive) The client key\n\n\n<a id=\"nestedatt--machine_secrets\"></a>\n### Nested Schema for `machine_secrets`\n\nRead-Only:\n\n- `certs` (Attributes) (see [below for nested schema](#nestedatt--machine_secrets--certs))\n- `cluster` (Attributes) The cluster secrets (see [below for nested schema](#nestedatt--machine_secrets--cluster))\n- `secrets` (Attributes) kubernetes cluster secrets (see [below for nested schema](#nestedatt--machine_secrets--secrets))\n- `trustdinfo` (Attributes) trustd secrets (see [below for nested schema](#nestedatt--machine_secrets--trustdinfo))\n\n<a id=\"nestedatt--machine_secrets--certs\"></a>\n### Nested Schema for `machine_secrets.certs`\n\nRead-Only:\n\n- `etcd` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--etcd))\n- `k8s` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s))\n- `k8s_aggregator` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s_aggregator))\n- `k8s_serviceaccount` (Attributes) The service account secrets (see [below for nested schema](#nestedatt--machine_secrets--certs--k8s_serviceaccount))\n- `os` (Attributes) The certificate and key pair (see [below for nested schema](#nestedatt--machine_secrets--certs--os))\n\n<a id=\"nestedatt--machine_secrets--certs--etcd\"></a>\n### Nested Schema for `machine_secrets.certs.etcd`\n\nRead-Only:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s\"></a>\n### Nested Schema for `machine_secrets.certs.k8s`\n\nRead-Only:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s_aggregator\"></a>\n### Nested Schema for `machine_secrets.certs.k8s_aggregator`\n\nRead-Only:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n<a id=\"nestedatt--machine_secrets--certs--k8s_serviceaccount\"></a>\n### Nested Schema for `machine_secrets.certs.k8s_serviceaccount`\n\nRead-Only:\n\n- `key` (String, Sensitive) The service account key\n\n\n<a id=\"nestedatt--machine_secrets--certs--os\"></a>\n### Nested Schema for `machine_secrets.certs.os`\n\nRead-Only:\n\n- `cert` (String) certificate data\n- `key` (String, Sensitive) key data\n\n\n\n<a id=\"nestedatt--machine_secrets--cluster\"></a>\n### Nested Schema for `machine_secrets.cluster`\n\nRead-Only:\n\n- `id` (String) The cluster ID\n- `secret` (String, Sensitive) The cluster secret\n\n\n<a id=\"nestedatt--machine_secrets--secrets\"></a>\n### Nested Schema for `machine_secrets.secrets`\n\nRead-Only:\n\n- `aescbc_encryption_secret` (String, Sensitive) The AES-CBC encryption secret\n- `bootstrap_token` (String, Sensitive) The bootstrap token\n- `secretbox_encryption_secret` (String, Sensitive) The secretbox encryption secret\n\n\n<a id=\"nestedatt--machine_secrets--trustdinfo\"></a>\n### Nested Schema for `machine_secrets.trustdinfo`\n\nRead-Only:\n\n- `token` (String, Sensitive) The trustd token\n## Import\n\nImport is supported using the following syntax:\n\n```terraform\n# machine secrets can be imported from an existing secrets file\nterraform import talos_machine_secrets.this <path-to-secrets.yaml>\n```\n"
  },
  {
    "path": "examples/README.md",
    "content": "# Talos provider examples\n\nThis directory contains a set of examples on using the Talos provider.\n"
  },
  {
    "path": "examples/data-sources/talos_client_configuration/data-source.tf",
    "content": "resource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_client_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n  nodes                = [\"10.5.0.2\"]\n}\n"
  },
  {
    "path": "examples/data-sources/talos_cluster_kubeconfig/data-source.tf",
    "content": "resource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  machine_type     = \"controlplane\"\n  cluster_endpoint = \"https://cluster.local:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\ndata \"talos_client_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n  nodes                = [\"10.5.0.2\"]\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.2\"\n  config_patches = [\n    yamlencode({\n      machine = {\n        install = {\n          disk = \"/dev/sdd\"\n        }\n      }\n    })\n  ]\n}\n\nresource \"talos_machine_bootstrap\" \"this\" {\n  depends_on = [\n    talos_machine_configuration_apply.this\n  ]\n  node                 = \"10.5.0.2\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n}\n\n\ndata \"talos_cluster_kubeconfig\" \"this\" {\n  depends_on = [\n    talos_machine_bootstrap.this\n  ]\n  client_configuration = talos_machine_secrets.this.client_configuration\n  node                 = \"10.5.0.2\"\n}\n"
  },
  {
    "path": "examples/data-sources/talos_image_factory_extensions_versions/data-source.tf",
    "content": "provider \"talos\" {}\n\ndata \"talos_image_factory_extensions_versions\" \"this\" {\n  # get the latest talos version\n  talos_version = \"v1.7.5\"\n  filters = {\n    names = [\n      \"amdgpu\",\n      \"tailscale\",\n    ]\n  }\n}\n"
  },
  {
    "path": "examples/data-sources/talos_image_factory_overlays_versions/data-source.tf",
    "content": "provider \"talos\" {}\n\ndata \"talos_image_factory_overlays_versions\" \"this\" {\n  # get the latest talos version\n  talos_version = \"v1.7.5\"\n  filters = {\n    name = \"rock4cplus\"\n  }\n}\n"
  },
  {
    "path": "examples/data-sources/talos_image_factory_urls/data-source.tf",
    "content": "data \"talos_image_factory_urls\" \"this\" {\n  talos_version = \"v1.7.5\"\n  schematic_id  = \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"\n  platform      = \"metal\"\n}\n\noutput \"installer_image\" {\n  value = data.talos_image_factory_urls.this.urls.installer\n}\n"
  },
  {
    "path": "examples/data-sources/talos_image_factory_versions/data-source.tf",
    "content": "provider \"talos\" {}\n\ndata \"talos_image_factory_versions\" \"this\" {}\n\noutput \"latest\" {\n  value = element(data.talos_image_factory_versions.this.talos_versions, length(data.talos_image_factory_versions.this.talos_versions) - 1)\n}\n"
  },
  {
    "path": "examples/data-sources/talos_machine_configuration/data-source.tf",
    "content": "resource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  machine_type     = \"controlplane\"\n  cluster_endpoint = \"https://cluster.local:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n"
  },
  {
    "path": "examples/data-sources/talos_machine_disks/data-source.tf",
    "content": "resource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_disks\" \"this\" {\n  client_configuration = talos_machine_secrets.this.client_configuration\n  node                 = \"10.5.0.2\"\n  selector             = \"disk.size > 6u * GB\"\n}\n\n# for example, this could be used to pass in a list of disks to rook-ceph\noutput \"nvme_disks\" {\n  value = data.talos_machine_disks.this.disks.*.name\n}\n"
  },
  {
    "path": "examples/ephemeral-resources/README.md",
    "content": "# Ephemeral Resources Examples\n\nThis directory contains examples demonstrating how to use ephemeral resources in the Talos provider to prevent secrets from being stored in Terraform state.\n\n## Prerequisites\n\n- **Terraform 1.11+** or **OpenTofu 1.11+** (required for ephemeral resources and write-only attributes)\n  - Note: Terraform 1.10 supports ephemeral resources but not write-only attributes\n  - Note: OpenTofu 1.11 introduced both features together (1.10 does not support ephemeral resources)\n- Talos provider 0.11.0 or later\n- HashiCorp Vault (or another secret manager)\n- Access to Talos nodes\n\n## Important: Secret Manager Requirement\n\n**These examples require a secret manager** (like HashiCorp Vault) to store machine secrets. Do not generate `ephemeral \"talos_machine_secrets\"` directly without persisting them, as this will create new secrets on every Terraform run, causing unpredictable infrastructure changes.\n\n### Why Secret Manager Integration is Required\n\nMachine secrets must remain stable throughout the cluster lifecycle. Without a secret manager:\n- New secrets generated on every `terraform plan` or `apply`\n- Dependent resources constantly show changes\n- Loss of cluster access when secrets regenerate\n- Non-deterministic infrastructure state\n\n### Setup Process\n\n1. **First time setup**: Generate and store machine secrets in Vault\n2. **Regular usage**: Retrieve secrets ephemerally from Vault\n3. **Always**: Use ephemeral machine configurations to avoid storing configs in state\n\nSee the [Using Ephemeral Resources Guide](../../docs/guides/using_ephemeral_resources.md) for detailed setup instructions.\n\n## Examples\n\n### Basic Example\n\nThe [basic](./basic/) example demonstrates:\n- Storing machine secrets in Vault (initial setup)\n- Retrieving machine secrets ephemerally from Vault\n- Creating machine configuration without storing secrets\n- Applying configuration using write-only attributes\n- Retrieving kubeconfig ephemerally\n\n## Key Benefits\n\n1. **Security**: Secrets never written to Terraform state\n2. **Stability**: Machine secrets remain constant across runs\n3. **Compliance**: Meets security policies requiring secret-free state\n4. **Deterministic**: Infrastructure state is reproducible and predictable\n\n## Learn More\n\n- [Using Ephemeral Resources Guide](../../docs/guides/using_ephemeral_resources.md)\n- [Ephemeral Resources Documentation](../../docs/ephemeral-resources/)\n- [Terraform Ephemeral Resources](https://developer.hashicorp.com/terraform/language/resources/ephemeral)\n- [Vault Ephemeral Resources](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/ephemeral-resources/kv_secret_v2)\n"
  },
  {
    "path": "examples/ephemeral-resources/basic/README.md",
    "content": "# Basic Ephemeral Resources Example\n\nThis example demonstrates the fundamental pattern for using ephemeral resources with the Talos provider and HashiCorp Vault.\n\n## What This Example Shows\n\n- How to store machine secrets in Vault (one-time setup)\n- How to retrieve machine secrets ephemerally from Vault\n- How to generate machine configurations without storing them in state\n- How to use write-only attributes to prevent secrets in state\n- How to retrieve kubeconfig ephemerally\n\n## Prerequisites\n\n- **Terraform 1.11+** or **OpenTofu 1.11+** (required for ephemeral resources and write-only attributes)\n- Talos provider 0.11.0 or later\n- HashiCorp Vault provider 5.0+\n- Vault instance accessible from Terraform\n- Talos node at 10.5.0.2 (or modify variables)\n\n## Setup Instructions\n\n### Step 1: Configure Vault Provider\n\nEnsure your Vault provider is configured with appropriate credentials:\n\n```bash\nexport VAULT_ADDR=\"https://vault.example.com:8200\"\nexport VAULT_TOKEN=\"your-vault-token\"\n```\n\nOr configure in your Terraform:\n\n```terraform\nprovider \"vault\" {\n  address = \"https://vault.example.com:8200\"\n}\n```\n\n### Step 2: Apply the Configuration\n\nSimply run:\n\n```bash\nterraform init\nterraform apply\n```\n\n**That's it!** On the first run, Terraform will:\n1. Generate machine secrets ephemerally\n2. Store them in Vault at `secret/data/talos-example-cluster`\n3. Retrieve them from Vault for immediate use\n4. Configure and bootstrap your Talos cluster\n\nAll in a single apply, thanks to Terraform's automatic dependency resolution.\n\n### Step 3: Verify Deterministic Behavior\n\nRun `terraform plan` again:\n\n```bash\nterraform plan\n```\n\nYou should see no changes. The secrets are now stable in Vault and retrieved ephemerally on each run.\n\n## Understanding the Pattern\n\n### Why Vault?\n\nWithout Vault:\n- `ephemeral \"talos_machine_secrets\"` would generate NEW secrets every run\n- Cluster access would be lost\n- All dependent resources would show changes\n\nWith Vault:\n- Secrets stored once on first run, retrieved ephemerally thereafter\n- Stable, deterministic infrastructure\n- No secrets in Terraform state\n- Works seamlessly in a single apply\n\n### What's Ephemeral?\n\n- **Machine secrets generation**: Only evaluated on first run (stored in Vault with hardcoded version)\n- **Machine secrets retrieval**: Retrieved from Vault on every run (never stored in state)\n- **Client configuration**: Retrieved from Vault on every run (never stored in state)\n- **Machine configuration**: Generated fresh each time (but deterministically from stable secrets)\n- **Kubeconfig**: Retrieved fresh each time from the cluster\n\n### The Magic of Hardcoded Version\n\nThe `data_json_wo_version = 1` in the Vault resource is key:\n- On first run: Secret doesn't exist, so Terraform generates it and stores version 1\n- On subsequent runs: Secret version 1 exists and matches, so no update needed\n- Since no update is needed, the `ephemeral \"talos_machine_secrets\"` isn't evaluated\n- This prevents regenerating secrets while keeping all code in place\n\n## Outputs\n\nThe example includes an ephemeral output for the kubeconfig:\n\n```terraform\noutput \"kubeconfig\" {\n  value     = ephemeral.talos_cluster_kubeconfig.this.kubeconfig_raw\n  sensitive = true\n  ephemeral = true\n}\n```\n\nAccess it with:\n\n```bash\nterraform output -raw kubeconfig > kubeconfig.yaml\nexport KUBECONFIG=kubeconfig.yaml\nkubectl get nodes\n```\n\n## Troubleshooting\n\n### \"No secret found at path\"\n\nEnsure you've completed Step 2 to store secrets in Vault first.\n\n### \"Resources keep changing on every plan\"\n\nCheck if the `data_json_wo_version` in the `vault_kv_secret_v2` resource is properly hardcoded. It should be set to a fixed value (e.g., `1`) to prevent regeneration.\n\n### \"Cannot connect to cluster\"\n\nVerify the secrets in Vault match what was originally used to configure the cluster. If you regenerated secrets, you'll need to reconfigure all cluster nodes.\n"
  },
  {
    "path": "examples/ephemeral-resources/basic/main.tf",
    "content": "terraform {\n  required_version = \">= 1.11\"\n  required_providers {\n    talos = {\n      source  = \"siderolabs/talos\"\n      version = \"~> 0.11\"\n    }\n    vault = {\n      source  = \"hashicorp/vault\"\n      version = \"~> 5.0\"\n    }\n  }\n}\n\n# This example demonstrates the correct pattern for using ephemeral resources\n# with Talos. Only machine_secrets is persisted to Vault — client_configuration\n# is a derived value regenerated on every apply from the CA key.\n\n# STEP 1: Generate and store machine secrets in Vault.\n# The ephemeral resource generates secrets, which are immediately stored in Vault\n# using write-only attributes. After the initial run, this ephemeral resource won't\n# be evaluated again because data_json_wo_version is hardcoded.\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nresource \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = \"secret\"\n  name  = \"talos-example-cluster\"\n\n  # Only machine_secrets is persisted — client_configuration is derived and never stored.\n  data_json_wo = jsonencode({\n    machine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n  })\n  # Hardcoded version prevents unnecessary refreshes after initial creation.\n  data_json_wo_version = 1\n}\n\n# STEP 2: Retrieve secrets ephemerally from Vault for cluster operations.\n# This ephemeral resource reads from Vault on every run, but values are never\n# stored in Terraform state.\nephemeral \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = vault_kv_secret_v2.talos_secrets.mount\n  name  = vault_kv_secret_v2.talos_secrets.name\n}\n\nlocals {\n  talos_data = jsondecode(ephemeral.vault_kv_secret_v2.talos_secrets.data_json)\n}\n\n# STEP 3: Generate client credentials from machine_secrets on every apply.\n# The cert is generated locally from the Talos OS CA key — no live API call.\n# A 10-year lifetime matches the CA so no rotation is needed within the cluster lifetime.\nephemeral \"talos_client_configuration\" \"this\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = local.talos_data.machine_secrets\n  crt_ttl         = \"87600h\"\n  endpoints       = [\"10.5.0.2\"]\n  nodes           = [\"10.5.0.2\"]\n}\n\n# STEP 4: Persist talos_config to Vault for operators to use with talosctl.\n# data_json_wo_version = 1 suppresses plan diffs after initial creation.\n# Bump the version to force a refresh (e.g. after a CA rotation).\nresource \"vault_kv_secret_v2\" \"talos_config\" {\n  mount = \"secret\"\n  name  = \"talos-example-cluster-config\"\n\n  data_json_wo = jsonencode({\n    talos_config = ephemeral.talos_client_configuration.this.talos_config\n  })\n  data_json_wo_version = 1\n}\n\n# Generate controlplane machine configuration using ephemeral secrets from Vault.\nephemeral \"talos_machine_configuration\" \"controlplane\" {\n  cluster_name     = \"example-cluster\"\n  cluster_endpoint = \"https://10.5.0.2:6443\"\n  machine_type     = \"controlplane\"\n  machine_secrets  = local.talos_data.machine_secrets\n\n  config_patches = [\n    yamlencode({\n      machine = {\n        install = {\n          disk = \"/dev/sda\"\n        }\n      }\n    })\n  ]\n}\n\n# Apply configuration to a machine.\nresource \"talos_machine_configuration_apply\" \"controlplane\" {\n  client_configuration_wo        = ephemeral.talos_client_configuration.this.client_configuration\n  machine_configuration_input_wo = ephemeral.talos_machine_configuration.controlplane.machine_configuration\n  node                           = \"10.5.0.2\"\n}\n\n# Bootstrap the cluster.\nresource \"talos_machine_bootstrap\" \"this\" {\n  client_configuration_wo = ephemeral.talos_client_configuration.this.client_configuration\n  node                    = \"10.5.0.2\"\n\n  depends_on = [\n    talos_machine_configuration_apply.controlplane\n  ]\n}\n\n# Wait for cluster to be healthy (ephemeral — doesn't leak secrets to state).\nephemeral \"talos_cluster_health\" \"this\" {\n  client_configuration   = ephemeral.talos_client_configuration.this.client_configuration\n  endpoints              = [\"10.5.0.2\"]\n  control_plane_nodes    = [\"10.5.0.2\"]\n  worker_nodes           = []\n  skip_kubernetes_checks = false\n\n  depends_on = [\n    talos_machine_bootstrap.this\n  ]\n}\n\n# Retrieve cluster kubeconfig ephemerally.\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n  client_configuration = ephemeral.talos_client_configuration.this.client_configuration\n  node                 = \"10.5.0.2\"\n\n  depends_on = [\n    ephemeral.talos_cluster_health.this\n  ]\n}\n\n# Output the kubeconfig (marked as ephemeral).\noutput \"kubeconfig\" {\n  value     = ephemeral.talos_cluster_kubeconfig.this.kubeconfig_raw\n  sensitive = true\n  ephemeral = true\n}\n"
  },
  {
    "path": "examples/ephemeral-resources/talos_cluster_kubeconfig/ephemeral-resource.tf",
    "content": "ephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n  endpoint        = \"https://10.5.0.2:6443\"\n}\n\n# Recommended pattern for stable kubeconfig when storing in a secret manager:\n# Persist not_before in terraform_data so the admin cert timestamps are fixed\n# across plan invocations and kubeconfig_raw is byte-identical on every open.\nresource \"terraform_data\" \"kubeconfig_nbf\" {\n  input = plantimestamp()\n  lifecycle {\n    ignore_changes = [input]\n  }\n}\n\nephemeral \"talos_cluster_kubeconfig\" \"stable\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n  endpoint        = \"https://10.5.0.2:6443\"\n  not_before      = terraform_data.kubeconfig_nbf.output\n  crt_ttl         = \"87600h\"\n}\n"
  },
  {
    "path": "examples/resources/talos_cluster_kubeconfig/resource.tf",
    "content": "resource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  machine_type     = \"controlplane\"\n  cluster_endpoint = \"https://cluster.local:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\ndata \"talos_client_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n  nodes                = [\"10.5.0.2\"]\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.2\"\n  config_patches = [\n    yamlencode({\n      machine = {\n        install = {\n          disk = \"/dev/sdd\"\n        }\n      }\n    })\n  ]\n}\n\nresource \"talos_machine_bootstrap\" \"this\" {\n  depends_on = [\n    talos_machine_configuration_apply.this\n  ]\n  node                 = \"10.5.0.2\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n}\n\n\nresource \"talos_cluster_kubeconfig\" \"this\" {\n  depends_on = [\n    talos_machine_bootstrap.this\n  ]\n  client_configuration = talos_machine_secrets.this.client_configuration\n  node                 = \"10.5.0.2\"\n}\n"
  },
  {
    "path": "examples/resources/talos_image_factory_schematic/resource.tf",
    "content": "provider \"talos\" {}\n\ndata \"talos_image_factory_extensions_versions\" \"this\" {\n  # get the latest talos version\n  talos_version = \"v1.7.5\"\n  filters = {\n    names = [\n      \"amdgpu\",\n      \"tailscale\",\n    ]\n  }\n}\n\nresource \"talos_image_factory_schematic\" \"this\" {\n  schematic = yamlencode(\n    {\n      customization = {\n        systemExtensions = {\n          officialExtensions = data.talos_image_factory_extensions_versions.this.extensions_info.*.name\n        }\n      }\n    }\n  )\n}\n\noutput \"schematic_id\" {\n  value = talos_image_factory_schematic.this.id\n}\n"
  },
  {
    "path": "examples/resources/talos_machine_bootstrap/import.sh",
    "content": "# machine bootstrap can be imported to let terraform know that the machine is already bootstrapped\nterraform import talos_machine_bootstrap.this <any id>\n"
  },
  {
    "path": "examples/resources/talos_machine_bootstrap/resource.tf",
    "content": "resource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  machine_type     = \"controlplane\"\n  cluster_endpoint = \"https://cluster.local:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\ndata \"talos_client_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n  nodes                = [\"10.5.0.2\"]\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.2\"\n  config_patches = [\n    yamlencode({\n      machine = {\n        install = {\n          disk = \"/dev/sdd\"\n        }\n      }\n    })\n  ]\n}\n\nresource \"talos_machine_bootstrap\" \"this\" {\n  depends_on = [\n    talos_machine_configuration_apply.this\n  ]\n  node                 = \"10.5.0.2\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n}\n"
  },
  {
    "path": "examples/resources/talos_machine_configuration_apply/resource.tf",
    "content": "resource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  machine_type     = \"controlplane\"\n  cluster_endpoint = \"https://cluster.local:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\ndata \"talos_client_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n  nodes                = [\"10.5.0.2\"]\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.2\"\n  config_patches = [\n    yamlencode({\n      machine = {\n        install = {\n          disk  = \"/dev/sdd\"\n          image = \"ghcr.io/siderolabs/installer:v1.12.6\"\n        }\n      }\n    })\n  ]\n}\n"
  },
  {
    "path": "examples/resources/talos_machine_secrets/import.sh",
    "content": "# machine secrets can be imported from an existing secrets file\nterraform import talos_machine_secrets.this <path-to-secrets.yaml>\n"
  },
  {
    "path": "examples/resources/talos_machine_secrets/resource.tf",
    "content": "resource \"talos_machine_secrets\" \"machine_secrets\" {}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/siderolabs/terraform-provider-talos\n\ngo 1.26.2\n\nrequire (\n\tgithub.com/blang/semver/v4 v4.0.0\n\tgithub.com/hashicorp/terraform-plugin-docs v0.24.0\n\tgithub.com/hashicorp/terraform-plugin-framework v1.19.0\n\tgithub.com/hashicorp/terraform-plugin-framework-timeouts v0.7.0\n\tgithub.com/hashicorp/terraform-plugin-framework-validators v0.19.0\n\tgithub.com/hashicorp/terraform-plugin-go v0.31.0\n\tgithub.com/hashicorp/terraform-plugin-log v0.10.0\n\tgithub.com/hashicorp/terraform-plugin-sdk/v2 v2.40.0\n\tgithub.com/hashicorp/terraform-plugin-testing v1.15.0\n\tgithub.com/siderolabs/crypto v0.6.5\n\tgithub.com/siderolabs/gen v0.8.6\n\tgithub.com/siderolabs/image-factory v1.1.0\n\tgithub.com/siderolabs/net v0.4.0\n\tgithub.com/siderolabs/talos v1.13.0\n\tgithub.com/siderolabs/talos/pkg/machinery v1.13.0\n\tgithub.com/stretchr/testify v1.11.1\n\tgo.yaml.in/yaml/v4 v4.0.0-rc.4\n\tgolang.org/x/crypto v0.50.0\n\tgolang.org/x/mod v0.35.0\n\tgoogle.golang.org/grpc v1.80.0\n\tk8s.io/client-go v0.35.4\n)\n\nrequire (\n\tgithub.com/ProtonMail/go-crypto v1.4.1 // indirect\n\tgithub.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f // indirect\n\tgithub.com/ProtonMail/gopenpgp/v2 v2.10.0 // indirect\n\tgithub.com/adrg/xdg v0.5.3 // indirect\n\tgithub.com/cloudflare/circl v1.6.3 // indirect\n\tgithub.com/gertd/go-pluralize v0.2.1 // indirect\n\tgithub.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect\n\tgithub.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect\n\tgithub.com/siderolabs/go-api-signature v0.3.12 // indirect\n\tgithub.com/siderolabs/protoenc v0.2.4 // indirect\n\tgo.uber.org/multierr v1.11.0 // indirect\n\tgo.uber.org/zap v1.27.1 // indirect\n)\n\nrequire (\n\tcel.dev/expr v0.25.1 // indirect\n\tgithub.com/BurntSushi/toml v1.2.1 // indirect\n\tgithub.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect\n\tgithub.com/Masterminds/goutils v1.1.1 // indirect\n\tgithub.com/Masterminds/semver/v3 v3.4.0 // indirect\n\tgithub.com/Masterminds/sprig/v3 v3.2.3 // indirect\n\tgithub.com/agext/levenshtein v1.2.2 // indirect\n\tgithub.com/antlr4-go/antlr/v4 v4.13.1 // indirect\n\tgithub.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect\n\tgithub.com/armon/go-radix v1.0.0 // indirect\n\tgithub.com/bgentry/speakeasy v0.1.0 // indirect\n\tgithub.com/bmatcuk/doublestar/v4 v4.9.1 // indirect\n\tgithub.com/cenkalti/backoff/v4 v4.3.0 // indirect\n\tgithub.com/containerd/go-cni v1.1.13 // indirect\n\tgithub.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect\n\tgithub.com/containernetworking/cni v1.3.0 // indirect\n\tgithub.com/cosi-project/runtime v1.14.1 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/distribution/reference v0.6.0 // indirect\n\tgithub.com/dustin/go-humanize v1.0.1 // indirect\n\tgithub.com/emicklei/dot v1.11.0 // indirect\n\tgithub.com/emicklei/go-restful/v3 v3.13.0 // indirect\n\tgithub.com/evanphx/json-patch v5.9.11+incompatible // indirect\n\tgithub.com/fatih/color v1.18.0 // indirect\n\tgithub.com/fxamacker/cbor/v2 v2.9.0 // indirect\n\tgithub.com/ghodss/yaml v1.0.0 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-openapi/jsonpointer v0.22.5 // indirect\n\tgithub.com/go-openapi/jsonreference v0.21.5 // indirect\n\tgithub.com/go-openapi/swag v0.25.5 // indirect\n\tgithub.com/go-openapi/swag/cmdutils v0.25.5 // indirect\n\tgithub.com/go-openapi/swag/conv v0.25.5 // indirect\n\tgithub.com/go-openapi/swag/fileutils v0.25.5 // indirect\n\tgithub.com/go-openapi/swag/jsonname v0.25.5 // indirect\n\tgithub.com/go-openapi/swag/jsonutils v0.25.5 // indirect\n\tgithub.com/go-openapi/swag/loading v0.25.5 // indirect\n\tgithub.com/go-openapi/swag/mangling v0.25.5 // indirect\n\tgithub.com/go-openapi/swag/netutils v0.25.5 // indirect\n\tgithub.com/go-openapi/swag/stringutils v0.25.5 // indirect\n\tgithub.com/go-openapi/swag/typeutils v0.25.5 // indirect\n\tgithub.com/go-openapi/swag/yamlutils v0.25.5 // indirect\n\tgithub.com/go-test/deep v1.1.1 // indirect\n\tgithub.com/golang/protobuf v1.5.4 // indirect\n\tgithub.com/google/cel-go v0.28.0 // indirect\n\tgithub.com/google/gnostic-models v0.7.1 // indirect\n\tgithub.com/google/go-cmp v0.7.0 // indirect\n\tgithub.com/google/go-containerregistry v0.21.5 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/hashicorp/cli v1.1.7 // indirect\n\tgithub.com/hashicorp/errwrap v1.1.0 // indirect\n\tgithub.com/hashicorp/go-checkpoint v0.5.0 // indirect\n\tgithub.com/hashicorp/go-cleanhttp v0.5.2 // indirect\n\tgithub.com/hashicorp/go-cty v1.5.0 // indirect\n\tgithub.com/hashicorp/go-hclog v1.6.3 // indirect\n\tgithub.com/hashicorp/go-multierror v1.1.1 // indirect\n\tgithub.com/hashicorp/go-plugin v1.7.0 // indirect\n\tgithub.com/hashicorp/go-retryablehttp v0.7.8 // indirect\n\tgithub.com/hashicorp/go-uuid v1.0.3 // indirect\n\tgithub.com/hashicorp/go-version v1.8.0 // indirect\n\tgithub.com/hashicorp/hc-install v0.9.3 // indirect\n\tgithub.com/hashicorp/hcl/v2 v2.24.0 // indirect\n\tgithub.com/hashicorp/logutils v1.0.0 // indirect\n\tgithub.com/hashicorp/terraform-exec v0.25.0 // indirect\n\tgithub.com/hashicorp/terraform-json v0.27.2 // indirect\n\tgithub.com/hashicorp/terraform-registry-address v0.4.0 // indirect\n\tgithub.com/hashicorp/terraform-svchost v0.1.1 // indirect\n\tgithub.com/hashicorp/yamux v0.1.2 // indirect\n\tgithub.com/huandu/xstrings v1.3.3 // indirect\n\tgithub.com/imdario/mergo v0.3.15 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/jsimonetti/rtnetlink/v2 v2.2.1-0.20260317095713-310581b9c6ac // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/klauspost/compress v1.18.5 // indirect\n\tgithub.com/mattn/go-colorable v0.1.14 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/mattn/go-runewidth v0.0.9 // indirect\n\tgithub.com/mdlayher/ethtool v0.5.1 // indirect\n\tgithub.com/mdlayher/genetlink v1.3.2 // indirect\n\tgithub.com/mdlayher/netlink v1.9.0 // indirect\n\tgithub.com/mdlayher/socket v0.5.1 // indirect\n\tgithub.com/mitchellh/copystructure v1.2.0 // indirect\n\tgithub.com/mitchellh/go-testing-interface v1.14.1 // indirect\n\tgithub.com/mitchellh/go-wordwrap v1.0.1 // indirect\n\tgithub.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect\n\tgithub.com/mitchellh/reflectwalk v1.0.2 // indirect\n\tgithub.com/moby/moby/api v1.54.1 // 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/oklog/run v1.1.0 // indirect\n\tgithub.com/opencontainers/go-digest v1.0.0 // indirect\n\tgithub.com/opencontainers/image-spec v1.1.1 // indirect\n\tgithub.com/opencontainers/runtime-spec v1.3.0 // indirect\n\tgithub.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect\n\tgithub.com/pkg/errors v0.9.1 // indirect\n\tgithub.com/planetscale/vtprotobuf v0.6.1-0.20250313105119-ba97887b0a25 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/posener/complete v1.2.3 // indirect\n\tgithub.com/ryanuber/go-glob v1.0.0 // indirect\n\tgithub.com/sasha-s/go-deadlock v0.3.6 // indirect\n\tgithub.com/shopspring/decimal v1.3.1 // indirect\n\tgithub.com/siderolabs/go-circular v0.2.3 // indirect\n\tgithub.com/siderolabs/go-kubernetes v0.2.36 // indirect\n\tgithub.com/siderolabs/go-pointer v1.0.1 // indirect\n\tgithub.com/siderolabs/go-procfs v0.1.2 // indirect\n\tgithub.com/siderolabs/go-retry v0.3.3 // indirect\n\tgithub.com/siderolabs/go-talos-support v0.2.1 // indirect\n\tgithub.com/spf13/cast v1.5.0 // indirect\n\tgithub.com/spf13/cobra v1.10.2 // indirect\n\tgithub.com/spf13/pflag v1.0.10 // indirect\n\tgithub.com/vbatts/tar-split v0.12.2 // indirect\n\tgithub.com/vmihailenco/msgpack v4.0.4+incompatible // indirect\n\tgithub.com/vmihailenco/msgpack/v5 v5.4.1 // indirect\n\tgithub.com/vmihailenco/tagparser/v2 v2.0.0 // indirect\n\tgithub.com/x448/float16 v0.8.4 // indirect\n\tgithub.com/yuin/goldmark v1.7.7 // indirect\n\tgithub.com/yuin/goldmark-meta v1.1.0 // indirect\n\tgithub.com/zclconf/go-cty v1.17.0 // indirect\n\tgo.abhg.dev/goldmark/frontmatter v0.2.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-20260218203240-3dfff04db8fa // indirect\n\tgolang.org/x/net v0.53.0 // indirect\n\tgolang.org/x/oauth2 v0.36.0 // indirect\n\tgolang.org/x/sync v0.20.0 // indirect\n\tgolang.org/x/sys v0.43.0 // indirect\n\tgolang.org/x/term v0.42.0 // indirect\n\tgolang.org/x/text v0.36.0 // indirect\n\tgolang.org/x/time v0.15.0 // indirect\n\tgolang.org/x/tools v0.44.0 // indirect\n\tgoogle.golang.org/appengine v1.6.8 // indirect\n\tgoogle.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect\n\tgoogle.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect\n\tgopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect\n\tgopkg.in/inf.v0 v0.9.1 // indirect\n\tgopkg.in/yaml.v2 v2.4.0 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n\tk8s.io/api v0.35.4 // indirect\n\tk8s.io/apimachinery v0.35.4 // indirect\n\tk8s.io/klog/v2 v2.140.0 // indirect\n\tk8s.io/kube-openapi v0.0.0-20260304202019-5b3e3fdb0acf // indirect\n\tk8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect\n\tsigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect\n\tsigs.k8s.io/randfill v1.0.0 // indirect\n\tsigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect\n\tsigs.k8s.io/yaml v1.6.0 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=\ncel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=\ndario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=\ndario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=\ngithub.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=\ngithub.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=\ngithub.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0=\ngithub.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc=\ngithub.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=\ngithub.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=\ngithub.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=\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/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=\ngithub.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=\ngithub.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=\ngithub.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=\ngithub.com/ProtonMail/go-crypto v1.4.1 h1:9RfcZHqEQUvP8RzecWEUafnZVtEvrBVL9BiF67IQOfM=\ngithub.com/ProtonMail/go-crypto v1.4.1/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo=\ngithub.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k=\ngithub.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw=\ngithub.com/ProtonMail/gopenpgp/v2 v2.10.0 h1:llCzLvntC9+iH+if/na4AgKTef/Zm4vpaRrR3+JdKvo=\ngithub.com/ProtonMail/gopenpgp/v2 v2.10.0/go.mod h1:dc0h9Pg3ftfN0U4pfRzujilfh61A2R52wgMkZWcWm2I=\ngithub.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=\ngithub.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=\ngithub.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=\ngithub.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=\ngithub.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=\ngithub.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=\ngithub.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=\ngithub.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=\ngithub.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=\ngithub.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=\ngithub.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\ngithub.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=\ngithub.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=\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/bmatcuk/doublestar/v4 v4.9.1 h1:X8jg9rRZmJd4yRy7ZeNDRnM+T3ZfHv15JiBJ/avrEXE=\ngithub.com/bmatcuk/doublestar/v4 v4.9.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=\ngithub.com/brianvoe/gofakeit/v7 v7.7.3 h1:RWOATEGpJ5EVg2nN8nlaEyaV/aB4d6c3GqYrbqQekss=\ngithub.com/brianvoe/gofakeit/v7 v7.7.3/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA=\ngithub.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=\ngithub.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=\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/cilium/ebpf v0.21.0 h1:4dpx1J/B/1apeTmWBH5BkVLayHTkFrMovVPnHEk+l3k=\ngithub.com/cilium/ebpf v0.21.0/go.mod h1:1kHKv6Kvh5a6TePP5vvvoMa1bclRyzUXELSs272fmIQ=\ngithub.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=\ngithub.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=\ngithub.com/containerd/go-cni v1.1.13 h1:eFSGOKlhoYNxpJ51KRIMHZNlg5UgocXEIEBGkY7Hnis=\ngithub.com/containerd/go-cni v1.1.13/go.mod h1:nTieub0XDRmvCZ9VI/SBG6PyqT95N4FIhxsauF1vSBI=\ngithub.com/containerd/stargz-snapshotter/estargz v0.18.2 h1:yXkZFYIzz3eoLwlTUZKz2iQ4MrckBxJjkmD16ynUTrw=\ngithub.com/containerd/stargz-snapshotter/estargz v0.18.2/go.mod h1:XyVU5tcJ3PRpkA9XS2T5us6Eg35yM0214Y+wvrZTBrY=\ngithub.com/containernetworking/cni v1.3.0 h1:v6EpN8RznAZj9765HhXQrtXgX+ECGebEYEmnuFjskwo=\ngithub.com/containernetworking/cni v1.3.0/go.mod h1:Bs8glZjjFfGPHMw6hQu82RUgEPNGEaBb9KS5KtNMnJ4=\ngithub.com/cosi-project/runtime v1.14.1 h1:1mxuH0zGXdJIy6762kaQsd+7C9MmzzuvIVIfWd867Os=\ngithub.com/cosi-project/runtime v1.14.1/go.mod h1:SfzpfNx7YwK8byi1X6ytikDXVMmbC7UpiCWdzntRf8M=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE=\ngithub.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=\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/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=\ngithub.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=\ngithub.com/docker/cli v29.4.0+incompatible h1:+IjXULMetlvWJiuSI0Nbor36lcJ5BTcVpUmB21KBoVM=\ngithub.com/docker/cli v29.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=\ngithub.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY=\ngithub.com/docker/docker-credential-helpers v0.9.5/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c=\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/emicklei/dot v1.11.0 h1:zsrhCuFHAJge/aZIC4N4LdHy5tqYu4tWEaUzIwdYj4Y=\ngithub.com/emicklei/dot v1.11.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=\ngithub.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=\ngithub.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=\ngithub.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=\ngithub.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=\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/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=\ngithub.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=\ngithub.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=\ngithub.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=\ngithub.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=\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/gertd/go-pluralize v0.2.1 h1:M3uASbVjMnTsPb0PNqg+E/24Vwigyo/tvyMTtAlLgiA=\ngithub.com/gertd/go-pluralize v0.2.1/go.mod h1:rbYaKDbsXxmRfr8uygAEKhOWsjyrrqrkHVpZvoOp8zk=\ngithub.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=\ngithub.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=\ngithub.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=\ngithub.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=\ngithub.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s=\ngithub.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M=\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-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA=\ngithub.com/go-openapi/jsonpointer v0.22.5/go.mod h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0=\ngithub.com/go-openapi/jsonreference v0.21.5 h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE=\ngithub.com/go-openapi/jsonreference v0.21.5/go.mod h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw=\ngithub.com/go-openapi/swag v0.25.5 h1:pNkwbUEeGwMtcgxDr+2GBPAk4kT+kJ+AaB+TMKAg+TU=\ngithub.com/go-openapi/swag v0.25.5/go.mod h1:B3RT6l8q7X803JRxa2e59tHOiZlX1t8viplOcs9CwTA=\ngithub.com/go-openapi/swag/cmdutils v0.25.5 h1:yh5hHrpgsw4NwM9KAEtaDTXILYzdXh/I8Whhx9hKj7c=\ngithub.com/go-openapi/swag/cmdutils v0.25.5/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0=\ngithub.com/go-openapi/swag/conv v0.25.5 h1:wAXBYEXJjoKwE5+vc9YHhpQOFj2JYBMF2DUi+tGu97g=\ngithub.com/go-openapi/swag/conv v0.25.5/go.mod h1:CuJ1eWvh1c4ORKx7unQnFGyvBbNlRKbnRyAvDvzWA4k=\ngithub.com/go-openapi/swag/fileutils v0.25.5 h1:B6JTdOcs2c0dBIs9HnkyTW+5gC+8NIhVBUwERkFhMWk=\ngithub.com/go-openapi/swag/fileutils v0.25.5/go.mod h1:V3cT9UdMQIaH4WiTrUc9EPtVA4txS0TOmRURmhGF4kc=\ngithub.com/go-openapi/swag/jsonname v0.25.5 h1:8p150i44rv/Drip4vWI3kGi9+4W9TdI3US3uUYSFhSo=\ngithub.com/go-openapi/swag/jsonname v0.25.5/go.mod h1:jNqqikyiAK56uS7n8sLkdaNY/uq6+D2m2LANat09pKU=\ngithub.com/go-openapi/swag/jsonutils v0.25.5 h1:XUZF8awQr75MXeC+/iaw5usY/iM7nXPDwdG3Jbl9vYo=\ngithub.com/go-openapi/swag/jsonutils v0.25.5/go.mod h1:48FXUaz8YsDAA9s5AnaUvAmry1UcLcNVWUjY42XkrN4=\ngithub.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5 h1:SX6sE4FrGb4sEnnxbFL/25yZBb5Hcg1inLeErd86Y1U=\ngithub.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5/go.mod h1:/2KvOTrKWjVA5Xli3DZWdMCZDzz3uV/T7bXwrKWPquo=\ngithub.com/go-openapi/swag/loading v0.25.5 h1:odQ/umlIZ1ZVRteI6ckSrvP6e2w9UTF5qgNdemJHjuU=\ngithub.com/go-openapi/swag/loading v0.25.5/go.mod h1:I8A8RaaQ4DApxhPSWLNYWh9NvmX2YKMoB9nwvv6oW6g=\ngithub.com/go-openapi/swag/mangling v0.25.5 h1:hyrnvbQRS7vKePQPHHDso+k6CGn5ZBs5232UqWZmJZw=\ngithub.com/go-openapi/swag/mangling v0.25.5/go.mod h1:6hadXM/o312N/h98RwByLg088U61TPGiltQn71Iw0NY=\ngithub.com/go-openapi/swag/netutils v0.25.5 h1:LZq2Xc2QI8+7838elRAaPCeqJnHODfSyOa7ZGfxDKlU=\ngithub.com/go-openapi/swag/netutils v0.25.5/go.mod h1:lHbtmj4m57APG/8H7ZcMMSWzNqIQcu0RFiXrPUara14=\ngithub.com/go-openapi/swag/stringutils v0.25.5 h1:NVkoDOA8YBgtAR/zvCx5rhJKtZF3IzXcDdwOsYzrB6M=\ngithub.com/go-openapi/swag/stringutils v0.25.5/go.mod h1:PKK8EZdu4QJq8iezt17HM8RXnLAzY7gW0O1KKarrZII=\ngithub.com/go-openapi/swag/typeutils v0.25.5 h1:EFJ+PCga2HfHGdo8s8VJXEVbeXRCYwzzr9u4rJk7L7E=\ngithub.com/go-openapi/swag/typeutils v0.25.5/go.mod h1:itmFmScAYE1bSD8C4rS0W+0InZUBrB2xSPbWt6DLGuc=\ngithub.com/go-openapi/swag/yamlutils v0.25.5 h1:kASCIS+oIeoc55j28T4o8KwlV2S4ZLPT6G0iq2SSbVQ=\ngithub.com/go-openapi/swag/yamlutils v0.25.5/go.mod h1:Gek1/SjjfbYvM+Iq4QGwa/2lEXde9n2j4a3wI3pNuOQ=\ngithub.com/go-openapi/testify/enable/yaml/v2 v2.4.0 h1:7SgOMTvJkM8yWrQlU8Jm18VeDPuAvB/xWrdxFJkoFag=\ngithub.com/go-openapi/testify/enable/yaml/v2 v2.4.0/go.mod h1:14iV8jyyQlinc9StD7w1xVPW3CO3q1Gj04Jy//Kw4VM=\ngithub.com/go-openapi/testify/v2 v2.4.0 h1:8nsPrHVCWkQ4p8h1EsRVymA2XABB4OT40gcvAu+voFM=\ngithub.com/go-openapi/testify/v2 v2.4.0/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=\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/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=\ngithub.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=\ngithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=\ngithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=\ngithub.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/cel-go v0.28.0 h1:KjSWstCpz/MN5t4a8gnGJNIYUsJRpdi/r97xWDphIQc=\ngithub.com/google/cel-go v0.28.0/go.mod h1:X0bD6iVNR8pkROSOoHVdgTkzmRcosof7WQqCD6wcMc8=\ngithub.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c=\ngithub.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\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/go-containerregistry v0.21.5 h1:KTJG9Pn/jC0VdZR6ctV3/jcN+q6/Iqlx0sTVz3ywZlM=\ngithub.com/google/go-containerregistry v0.21.5/go.mod h1:ySvMuiWg+dOsRW0Hw8GYwfMwBlNRTmpYBFJPlkco5zU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=\ngithub.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=\ngithub.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\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.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c=\ngithub.com/hashicorp/cli v1.1.7 h1:/fZJ+hNdwfTSfsxMBa9WWMlfjUZbX8/LnUxgAd7lCVU=\ngithub.com/hashicorp/cli v1.1.7/go.mod h1:e6Mfpga9OCT1vqzFuoGZiiF/KaG9CbUfO5s3ghU3YgU=\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-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU=\ngithub.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=\ngithub.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=\ngithub.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=\ngithub.com/hashicorp/go-cty v1.5.0 h1:EkQ/v+dDNUqnuVpmS5fPqyY71NXVgT5gf32+57xY8g0=\ngithub.com/hashicorp/go-cty v1.5.0/go.mod h1:lFUCG5kd8exDobgSfyj4ONE/dc822kiYMguVKdHGMLM=\ngithub.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=\ngithub.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=\ngithub.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=\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/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA=\ngithub.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=\ngithub.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48=\ngithub.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw=\ngithub.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=\ngithub.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=\ngithub.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=\ngithub.com/hashicorp/hc-install v0.9.3 h1:1H4dgmgzxEVwT6E/d/vIL5ORGVKz9twRwDw+qA5Hyho=\ngithub.com/hashicorp/hc-install v0.9.3/go.mod h1:FQlQ5I3I/X409N/J1U4pPeQQz1R3BoV0IysB7aiaQE0=\ngithub.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE=\ngithub.com/hashicorp/hcl/v2 v2.24.0/go.mod h1:oGoO1FIQYfn/AgyOhlg9qLC6/nOJPX3qGbkZpYAcqfM=\ngithub.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=\ngithub.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=\ngithub.com/hashicorp/terraform-exec v0.25.0 h1:Bkt6m3VkJqYh+laFMrWIpy9KHYFITpOyzRMNI35rNaY=\ngithub.com/hashicorp/terraform-exec v0.25.0/go.mod h1:dl9IwsCfklDU6I4wq9/StFDp7dNbH/h5AnfS1RmiUl8=\ngithub.com/hashicorp/terraform-json v0.27.2 h1:BwGuzM6iUPqf9JYM/Z4AF1OJ5VVJEEzoKST/tRDBJKU=\ngithub.com/hashicorp/terraform-json v0.27.2/go.mod h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE=\ngithub.com/hashicorp/terraform-plugin-docs v0.24.0 h1:YNZYd+8cpYclQyXbl1EEngbld8w7/LPOm99GD5nikIU=\ngithub.com/hashicorp/terraform-plugin-docs v0.24.0/go.mod h1:YLg+7LEwVmRuJc0EuCw0SPLxuQXw5mW8iJ5ml/kvi+o=\ngithub.com/hashicorp/terraform-plugin-framework v1.19.0 h1:q0bwyhxAOR3vfdgbk9iplv3MlTv/dhBHTXjQOtQDoBA=\ngithub.com/hashicorp/terraform-plugin-framework v1.19.0/go.mod h1:YRXOBu0jvs7xp4AThBbX4mAzYaMJ1JgtFH//oGKxwLc=\ngithub.com/hashicorp/terraform-plugin-framework-timeouts v0.7.0 h1:jblRy1PkLfPm5hb5XeMa3tezusnMRziUGqtT5epSYoI=\ngithub.com/hashicorp/terraform-plugin-framework-timeouts v0.7.0/go.mod h1:5jm2XK8uqrdiSRfD5O47OoxyGMCnwTcl8eoiDgSa+tc=\ngithub.com/hashicorp/terraform-plugin-framework-validators v0.19.0 h1:Zz3iGgzxe/1XBkooZCewS0nJAaCFPFPHdNJd8FgE4Ow=\ngithub.com/hashicorp/terraform-plugin-framework-validators v0.19.0/go.mod h1:GBKTNGbGVJohU03dZ7U8wHqc2zYnMUawgCN+gC0itLc=\ngithub.com/hashicorp/terraform-plugin-go v0.31.0 h1:0Fz2r9DQ+kNNl6bx8HRxFd1TfMKUvnrOtvJPmp3Z0q8=\ngithub.com/hashicorp/terraform-plugin-go v0.31.0/go.mod h1:A88bDhd/cW7FnwqxQRz3slT+QY6yzbHKc6AOTtmdeS8=\ngithub.com/hashicorp/terraform-plugin-log v0.10.0 h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g=\ngithub.com/hashicorp/terraform-plugin-log v0.10.0/go.mod h1:/9RR5Cv2aAbrqcTSdNmY1NRHP4E3ekrXRGjqORpXyB0=\ngithub.com/hashicorp/terraform-plugin-sdk/v2 v2.40.0 h1:MKS/2URqeJRwJdbOfcbdsZCq/IRrNkqJNN0GtVIsuGs=\ngithub.com/hashicorp/terraform-plugin-sdk/v2 v2.40.0/go.mod h1:PuG4P97Ju3QXW6c6vRkRadWJbvnEu2Xh+oOuqcYOqX4=\ngithub.com/hashicorp/terraform-plugin-testing v1.15.0 h1:/fimKyl0YgD7aAtJkuuAZjwBASXhCIwWqMbDLnKLMe4=\ngithub.com/hashicorp/terraform-plugin-testing v1.15.0/go.mod h1:bGXMw7bE95EiZhSBV3rM2W8TiffaPTDuLS+HFI/lIYs=\ngithub.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk=\ngithub.com/hashicorp/terraform-registry-address v0.4.0/go.mod h1:LRS1Ay0+mAiRkUyltGT+UHWkIqTFvigGn/LbMshfflE=\ngithub.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=\ngithub.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc=\ngithub.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=\ngithub.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=\ngithub.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=\ngithub.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=\ngithub.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=\ngithub.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=\ngithub.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=\ngithub.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=\ngithub.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=\ngithub.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=\ngithub.com/jsimonetti/rtnetlink/v2 v2.2.1-0.20260317095713-310581b9c6ac h1:UfziP9RaDM6D+f+yNdL3T/N1DztwltLDGBkpybF/fYs=\ngithub.com/jsimonetti/rtnetlink/v2 v2.2.1-0.20260317095713-310581b9c6ac/go.mod h1:A/gqt1BEMJcvzGQJXQ3SnsDOQL7QRNhxTiC3eb++608=\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/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=\ngithub.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=\ngithub.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=\ngithub.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\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/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=\ngithub.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=\ngithub.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=\ngithub.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mdlayher/ethtool v0.5.1 h1:U4GThY6WgNJUJsMrUzBmoOTdQHFWxFPTHTeNnn3GCvU=\ngithub.com/mdlayher/ethtool v0.5.1/go.mod h1:Pz39PaAy96Ea1SrCvEO/pPEAeULvRJjO6zspuEMhJy4=\ngithub.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw=\ngithub.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o=\ngithub.com/mdlayher/netlink v1.9.0 h1:G8+GLq2x3v4D4MVIqDdNUhTUC7TKiCy/6MDkmItfKco=\ngithub.com/mdlayher/netlink v1.9.0/go.mod h1:YBnl5BXsCoRuwBjKKlZ+aYmEoq0r12FDA/3JC+94KDg=\ngithub.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=\ngithub.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ=\ngithub.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=\ngithub.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=\ngithub.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=\ngithub.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=\ngithub.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=\ngithub.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=\ngithub.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=\ngithub.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=\ngithub.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE=\ngithub.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=\ngithub.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=\ngithub.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=\ngithub.com/moby/moby/api v1.54.1 h1:TqVzuJkOLsgLDDwNLmYqACUuTehOHRGKiPhvH8V3Nn4=\ngithub.com/moby/moby/api v1.54.1/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs=\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/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=\ngithub.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=\ngithub.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=\ngithub.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=\ngithub.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=\ngithub.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=\ngithub.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=\ngithub.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=\ngithub.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=\ngithub.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=\ngithub.com/opencontainers/runtime-spec v1.3.0 h1:YZupQUdctfhpZy3TM39nN9Ika5CBWT5diQ8ibYCRkxg=\ngithub.com/opencontainers/runtime-spec v1.3.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=\ngithub.com/petermattis/goid v0.0.0-20250813065127-a731cc31b4fe/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=\ngithub.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 h1:rh2lKw/P/EqHa724vYH2+VVQ1YnW4u6EOXl0PMAovZE=\ngithub.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=\ngithub.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=\ngithub.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=\ngithub.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=\ngithub.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/planetscale/vtprotobuf v0.6.1-0.20250313105119-ba97887b0a25 h1:S1hI5JiKP7883xBzZAr1ydcxrKNSVNm7+3+JwjxZEsg=\ngithub.com/planetscale/vtprotobuf v0.6.1-0.20250313105119-ba97887b0a25/go.mod h1:ZQntvDG8TkPgljxtA0R9frDoND4QORU1VXz015N5Ks4=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=\ngithub.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=\ngithub.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=\ngithub.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=\ngithub.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=\ngithub.com/sasha-s/go-deadlock v0.3.6 h1:TR7sfOnZ7x00tWPfD397Peodt57KzMDo+9Ae9rMiUmw=\ngithub.com/sasha-s/go-deadlock v0.3.6/go.mod h1:CUqNyyvMxTyjFqDT7MRg9mb4Dv/btmGTqSR+rky/UXo=\ngithub.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=\ngithub.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=\ngithub.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=\ngithub.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=\ngithub.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=\ngithub.com/siderolabs/crypto v0.6.5 h1:Elq5tpWP2ApZ4Y+Kg+eIDiiWbmriCPI1mjYIMwvsYkw=\ngithub.com/siderolabs/crypto v0.6.5/go.mod h1:QjVcrdJQE1sxhjHqieCgwGdlIYq/xCP2DL53Up8nbU4=\ngithub.com/siderolabs/gen v0.8.6 h1:pE6shuqov3L+5rEcAUJ/kY6iJofimljQw5G95P8a5c4=\ngithub.com/siderolabs/gen v0.8.6/go.mod h1:J9IbusbES2W6QWjtSHpDV9iPGZHc978h1+KJ4oQRspQ=\ngithub.com/siderolabs/go-api-signature v0.3.12 h1:i1X+kPh9fzo+lEjtEplZSbtq1p21vKv4FCWJcB/ozvk=\ngithub.com/siderolabs/go-api-signature v0.3.12/go.mod h1:dPLiXohup4qHX7KUgF/wwOE3lRU5uAr3ssEomNxiyxY=\ngithub.com/siderolabs/go-circular v0.2.3 h1:GKkA1Tw79kEFGtWdl7WTxEUTbwtklITeiRT0V1McHrA=\ngithub.com/siderolabs/go-circular v0.2.3/go.mod h1:YBN/q9YpQphUYnBtBgPsngauSHj1TEZfgQZWZVjk1WE=\ngithub.com/siderolabs/go-kubernetes v0.2.36 h1:n8p6c7M0kDnrm9WoQ8njHUs/k3o//kEh9t0eFsnHp9Q=\ngithub.com/siderolabs/go-kubernetes v0.2.36/go.mod h1:jQAuwnqjGD0wakL5OYJz8LrX2eYoDqgKrS2TnqesUoU=\ngithub.com/siderolabs/go-pointer v1.0.1 h1:f7Yi4IK1jptS8yrT9GEbwhmGcVxvPQgBUG/weH3V3DM=\ngithub.com/siderolabs/go-pointer v1.0.1/go.mod h1:C8Q/3pNHT4RE9e4rYR9PHeS6KPMlStRBgYrJQJNy/vA=\ngithub.com/siderolabs/go-procfs v0.1.2 h1:bDs9hHyYGE2HO1frpmUsD60yg80VIEDrx31fkbi4C8M=\ngithub.com/siderolabs/go-procfs v0.1.2/go.mod h1:dBzQXobsM7+TWRRI3DS9X7vAuj8Nkfgu3Z/U9iY3ZTY=\ngithub.com/siderolabs/go-retry v0.3.3 h1:zKV+S1vumtO72E6sYsLlmIdV/G/GcYSBLiEx/c9oCEg=\ngithub.com/siderolabs/go-retry v0.3.3/go.mod h1:Ff/VGc7v7un4uQg3DybgrmOWHEmJ8BzZds/XNn/BqMI=\ngithub.com/siderolabs/go-talos-support v0.2.1 h1:QVFhcmGw1ZTTXEtukBgrdjNxYbsPAOTMpopisV4EbgU=\ngithub.com/siderolabs/go-talos-support v0.2.1/go.mod h1:tfwP9mpPdmqLU8DuCDgcAd0ficLlJuB/XMtrIV8g+20=\ngithub.com/siderolabs/image-factory v1.1.0 h1:M5OZXPKQtBlUbzzH9PSP+ydp75S3mdYyiLXo7BoX9mc=\ngithub.com/siderolabs/image-factory v1.1.0/go.mod h1:cequkUpOoM+D1fA5kQrs573aLFwoqTPMAAeA1N1poog=\ngithub.com/siderolabs/net v0.4.0 h1:1bOgVay/ijPkJz4qct98nHsiB/ysLQU0KLoBC4qLm7I=\ngithub.com/siderolabs/net v0.4.0/go.mod h1:/ibG+Hm9HU27agp5r9Q3eZicEfjquzNzQNux5uEk0kM=\ngithub.com/siderolabs/protoenc v0.2.4 h1:D3Fpn2nQSQOhl8ZlAxijZAf7K6F8CM1uZq0afIGsr8Q=\ngithub.com/siderolabs/protoenc v0.2.4/go.mod h1:i5XLHjfv5vyi7LhQrSEo19HCA+lYtDd7CWxsoWp9XE8=\ngithub.com/siderolabs/talos v1.13.0 h1:4KXRbxCZ/8FtXRV/cEaouW8K/LjRkBLG7a42dsNLe8M=\ngithub.com/siderolabs/talos v1.13.0/go.mod h1:Lvg9a5c4rxCjl8fos3akomDn2mqWFXwzNPbgZMNnE94=\ngithub.com/siderolabs/talos/pkg/machinery v1.13.0 h1:nNfAUqgD/yOb4RZAc3xrQXKYllIK36RPaJacNQQC3TI=\ngithub.com/siderolabs/talos/pkg/machinery v1.13.0/go.mod h1:70Up2PI+g6wxW4rJ8AIlZO0MfQ8gglyfqsyBv0PdnSo=\ngithub.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=\ngithub.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=\ngithub.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=\ngithub.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=\ngithub.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=\ngithub.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=\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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\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.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=\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/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4=\ngithub.com/vbatts/tar-split v0.12.2/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=\ngithub.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=\ngithub.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=\ngithub.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=\ngithub.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=\ngithub.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=\ngithub.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=\ngithub.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=\ngithub.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=\ngithub.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=\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/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=\ngithub.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngithub.com/yuin/goldmark v1.7.7 h1:5m9rrB1sW3JUMToKFQfb+FGt1U7r57IHu5GrYrG2nqU=\ngithub.com/yuin/goldmark v1.7.7/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=\ngithub.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=\ngithub.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=\ngithub.com/zclconf/go-cty v1.17.0 h1:seZvECve6XX4tmnvRzWtJNHdscMtYEx5R7bnnVyd/d0=\ngithub.com/zclconf/go-cty v1.17.0/go.mod h1:wqFzcImaLTI6A5HfsRwB0nj5n0MRZFwmey8YoFPPs3U=\ngithub.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=\ngithub.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=\ngo.abhg.dev/goldmark/frontmatter v0.2.0 h1:P8kPG0YkL12+aYk2yU3xHv4tcXzeVnN+gU0tJ5JnxRw=\ngo.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px76YjkOzhB4YlU=\ngo.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=\ngo.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=\ngo.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=\ngo.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=\ngo.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=\ngo.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=\ngo.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=\ngo.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=\ngo.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=\ngo.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=\ngo.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=\ngo.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=\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=\ngo.yaml.in/yaml/v4 v4.0.0-rc.4 h1:UP4+v6fFrBIb1l934bDl//mmnoIZEDK0idg1+AIvX5U=\ngo.yaml.in/yaml/v4 v4.0.0-rc.4/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=\ngolang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=\ngolang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=\ngolang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0=\ngolang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=\ngolang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=\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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=\ngolang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=\ngolang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=\ngolang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=\ngolang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=\ngolang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=\ngolang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=\ngolang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=\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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=\ngolang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=\ngolang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=\ngolang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=\ngolang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=\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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=\ngolang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=\ngolang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=\ngonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=\ngoogle.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 h1:41r6JMbpzBMen0R/4TZeeAmGXSJC7DftGINUodzTkPI=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=\ngoogle.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=\ngoogle.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=\ngoogle.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/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-20180628173108-788fd7840127/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.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=\ngopkg.in/evanphx/json-patch.v4 v4.13.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/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=\ngopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\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.35.4 h1:P7nFYKl5vo9AGUp1Z+Pmd3p2tA7bX2wbFWCvDeRv988=\nk8s.io/api v0.35.4/go.mod h1:yl4lqySWOgYJJf9RERXKUwE9g2y+CkuwG+xmcOK8wXU=\nk8s.io/apimachinery v0.35.4 h1:xtdom9RG7e+yDp71uoXoJDWEE2eOiHgeO4GdBzwWpds=\nk8s.io/apimachinery v0.35.4/go.mod h1:NNi1taPOpep0jOj+oRha3mBJPqvi0hGdaV8TCqGQ+cc=\nk8s.io/client-go v0.35.4 h1:DN6fyaGuzK64UvnKO5fOA6ymSjvfGAnCAHAR0C66kD8=\nk8s.io/client-go v0.35.4/go.mod h1:2Pg9WpsS4NeOpoYTfHHfMxBG8zFMSAUi4O/qoiJC3nY=\nk8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=\nk8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=\nk8s.io/kube-openapi v0.0.0-20260304202019-5b3e3fdb0acf h1:btPscg4cMql0XdYK2jLsJcNEKmACJz8l+U7geC06FiM=\nk8s.io/kube-openapi v0.0.0-20260304202019-5b3e3fdb0acf/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=\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/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=\nsigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/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.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8=\nsigs.k8s.io/structured-merge-diff/v6 v6.3.2/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": "hack/release.sh",
    "content": "#!/usr/bin/env bash\n\n# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.\n#\n# Generated on 2024-08-29T12:20:48Z by kres b5ca957.\n\nset -e\n\nRELEASE_TOOL_IMAGE=\"ghcr.io/siderolabs/release-tool:latest\"\n\nfunction release-tool {\n  docker pull \"${RELEASE_TOOL_IMAGE}\" >/dev/null\n  docker run --rm -w /src -v \"${PWD}\":/src:ro \"${RELEASE_TOOL_IMAGE}\" -l -d -n -t \"${1}\" ./hack/release.toml\n}\n\nfunction changelog {\n  if [ \"$#\" -eq 1 ]; then\n    (release-tool ${1}; echo; cat CHANGELOG.md) > CHANGELOG.md- && mv CHANGELOG.md- CHANGELOG.md\n  else\n    echo 1>&2 \"Usage: $0 changelog [tag]\"\n    exit 1\n  fi\n}\n\nfunction release-notes {\n  release-tool \"${2}\" > \"${1}\"\n}\n\nfunction cherry-pick {\n  if [ $# -ne 2 ]; then\n    echo 1>&2 \"Usage: $0 cherry-pick <commit> <branch>\"\n    exit 1\n  fi\n\n  git checkout $2\n  git fetch\n  git rebase upstream/$2\n  git cherry-pick -x $1\n}\n\nfunction commit {\n  if [ $# -ne 1 ]; then\n    echo 1>&2 \"Usage: $0 commit <tag>\"\n    exit 1\n  fi\n\n  if is_on_main_branch; then\n    update_license_files\n  fi\n\n  git commit -s -m \"release($1): prepare release\" -m \"This is the official $1 release.\"\n}\n\nfunction is_on_main_branch {\n  main_remotes=(\"upstream\" \"origin\")\n  branch_names=(\"main\" \"master\")\n  current_branch=$(git rev-parse --abbrev-ref HEAD)\n\n  echo \"Check current branch: $current_branch\"\n\n  for remote in \"${main_remotes[@]}\"; do\n    echo \"Fetch remote $remote...\"\n\n    if ! git fetch --quiet \"$remote\" &>/dev/null; then\n      echo \"Failed to fetch $remote, skip...\"\n\n      continue\n    fi\n\n    for branch_name in \"${branch_names[@]}\"; do\n      if ! git rev-parse --verify \"$branch_name\" &>/dev/null; then\n        echo \"Branch $branch_name does not exist, skip...\"\n\n        continue\n      fi\n\n      echo \"Branch $remote/$branch_name exists, comparing...\"\n\n      merge_base=$(git merge-base \"$current_branch\" \"$remote/$branch_name\")\n      latest_main=$(git rev-parse \"$remote/$branch_name\")\n\n      if [ \"$merge_base\" = \"$latest_main\" ]; then\n        echo \"Current branch is up-to-date with $remote/$branch_name\"\n\n        return 0\n      else\n        echo \"Current branch is not on $remote/$branch_name\"\n\n        return 1\n      fi\n    done\n  done\n\n  echo \"No main or master branch found on any remote\"\n\n  return 1\n}\n\nfunction update_license_files {\n  script_dir=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n  parent_dir=\"$(dirname \"$script_dir\")\"\n  current_year=$(date +\"%Y\")\n  change_date=$(date -v+4y +\"%Y-%m-%d\" 2>/dev/null || date -d \"+4 years\" +\"%Y-%m-%d\" 2>/dev/null || date --date=\"+4 years\" +\"%Y-%m-%d\")\n\n  # Find LICENSE and .kres.yaml files recursively in the parent directory (project root)\n  find \"$parent_dir\" \\( -name \"LICENSE\" -o -name \".kres.yaml\" \\) -type f | while read -r file; do\n    temp_file=\"${file}.tmp\"\n\n    if [[ $file == *\"LICENSE\" ]]; then\n      if grep -q \"^Business Source License\" \"$file\"; then\n        sed -e \"s/The Licensed Work is (c) [0-9]\\{4\\}/The Licensed Work is (c) $current_year/\" \\\n          -e \"s/Change Date:          [0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}/Change Date:          $change_date/\" \\\n          \"$file\" >\"$temp_file\"\n      else\n        continue # Not a Business Source License file\n      fi\n    elif [[ $file == *\".kres.yaml\" ]]; then\n      sed -E 's/^([[:space:]]*)ChangeDate:.*$/\\1ChangeDate: \"'\"$change_date\"'\"/' \"$file\" >\"$temp_file\"\n    fi\n\n    # Check if the file has changed\n    if ! cmp -s \"$file\" \"$temp_file\"; then\n      mv \"$temp_file\" \"$file\"\n      echo \"Updated: $file\"\n      git add \"$file\"\n    else\n      echo \"No changes: $file\"\n      rm \"$temp_file\"\n    fi\n  done\n}\n\nif declare -f \"$1\" > /dev/null\nthen\n  cmd=\"$1\"\n  shift\n  $cmd \"$@\"\nelse\n  cat <<EOF\nUsage:\n  commit:        Create the official release commit message (updates BUSL license dates if there is any).\n  cherry-pick:   Cherry-pick a commit into a release branch.\n  changelog:     Update the specified CHANGELOG.\n  release-notes: Create release notes for GitHub release.\nEOF\n\n  exit 1\nfi\n"
  },
  {
    "path": "hack/release.toml",
    "content": "# commit to be tagged for the new release\ncommit = \"HEAD\"\n\nproject_name = \"terraform-provider-talos\"\ngithub_repo = \"siderolabs/terraform-provider-talos\"\nignore_deps = [\"google.golang.org/grpc\"]\n\nprevious = \"v0.10.1\"\npre_release = false\n\n[notes]\n\n    [notes.updates]\n        title = \"Component Updates\"\n        description = \"\"\"\\\nTalos sdk: v1.13.0\n\"\"\"\n\n    [notes.config_patches]\n        title = \"ephemeral resources\"\n        description = \"\"\"\\\nNew ephemeral resources are added, please see docs.\n\"\"\"\n"
  },
  {
    "path": "main.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n// Package main is the entrypoint for the provider server.\npackage main\n\nimport (\n\t\"context\"\n\t\"flag\"\n\t\"log\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework/providerserver\"\n\n\t\"github.com/siderolabs/terraform-provider-talos/pkg/talos\"\n)\n\n// Run \"go generate\" to format example terraform files and generate the docs for the registry/website\n\n// If you do not have terraform installed, you can remove the formatting command, but its suggested to\n// ensure the documentation is formatted properly.\n//go:generate terraform fmt -recursive ./examples/\n\n// Provider documentation generation.\n//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs generate --provider-name talos\n\nfunc main() {\n\tvar debug bool\n\n\tflag.BoolVar(&debug, \"debug\", false, \"set to true to run the provider with support for debuggers like delve\")\n\tflag.Parse()\n\n\topts := providerserver.ServeOpts{\n\t\tAddress: \"registry.terraform.io/siderolabs/talos\",\n\t\tDebug:   debug,\n\t}\n\n\terr := providerserver.Serve(context.Background(), talos.New, opts)\n\tif err != nil {\n\t\tlog.Fatal(err.Error())\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/client_configuration_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos // nolint:testpackage // needs access to internal functions\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework/attr\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n)\n\n// TestGetClientConfigurationValues_Typed tests extraction from a properly-typed ObjectValue\n// (created via the clientConfiguration struct).\nfunc TestGetClientConfigurationValues_Typed(t *testing.T) {\n\tt.Parallel()\n\n\tctx := context.Background()\n\n\t// Create a properly-typed ObjectValue using the clientConfiguration struct\n\tconfig := clientConfiguration{\n\t\tCA:   types.StringValue(\"test-ca-cert\"),\n\t\tCert: types.StringValue(\"test-client-cert\"),\n\t\tKey:  types.StringValue(\"test-client-key\"),\n\t}\n\n\tobjValue, diags := types.ObjectValueFrom(ctx, map[string]attr.Type{\n\t\t\"ca_certificate\":     types.StringType,\n\t\t\"client_certificate\": types.StringType,\n\t\t\"client_key\":         types.StringType,\n\t}, config)\n\n\tif diags.HasError() {\n\t\tt.Fatalf(\"Failed to create ObjectValue: %v\", diags)\n\t}\n\n\t// Test extraction\n\tca, cert, key, errMsg, ok := getClientConfigurationValues(ctx, objValue)\n\n\tif !ok {\n\t\tt.Fatalf(\"Expected extraction to succeed, got error: %s\", errMsg)\n\t}\n\n\tif ca != \"test-ca-cert\" {\n\t\tt.Errorf(\"Expected ca='test-ca-cert', got '%s'\", ca)\n\t}\n\n\tif cert != \"test-client-cert\" {\n\t\tt.Errorf(\"Expected cert='test-client-cert', got '%s'\", cert)\n\t}\n\n\tif key != \"test-client-key\" {\n\t\tt.Errorf(\"Expected key='test-client-key', got '%s'\", key)\n\t}\n}\n\n// TestGetClientConfigurationValues_Reconstructed tests extraction from a reconstructed ObjectValue\n// (plain map with correct keys, as returned from Vault round-trip without full schema metadata).\n// This test demonstrates the issue where .As() fails on reconstructed maps.\nfunc TestGetClientConfigurationValues_Reconstructed(t *testing.T) {\n\tt.Parallel()\n\n\tctx := context.Background()\n\n\t// Create an ObjectValue from a plain map (simulating Vault reconstruction)\n\t// This is what happens when you do:\n\t//   client_configuration = {\n\t//     ca_certificate     = vault_data[\"ca\"]\n\t//     client_certificate = vault_data[\"cert\"]\n\t//     client_key         = vault_data[\"key\"]\n\t//   }\n\tobjValue, diags := types.ObjectValue(\n\t\tmap[string]attr.Type{\n\t\t\t\"ca_certificate\":     types.StringType,\n\t\t\t\"client_certificate\": types.StringType,\n\t\t\t\"client_key\":         types.StringType,\n\t\t},\n\t\tmap[string]attr.Value{\n\t\t\t\"ca_certificate\":     basetypes.NewStringValue(\"vault-ca-cert\"),\n\t\t\t\"client_certificate\": basetypes.NewStringValue(\"vault-client-cert\"),\n\t\t\t\"client_key\":         basetypes.NewStringValue(\"vault-client-key\"),\n\t\t},\n\t)\n\n\tif diags.HasError() {\n\t\tt.Fatalf(\"Failed to create ObjectValue: %v\", diags)\n\t}\n\n\t// Test extraction using the fallback path that handles plain maps (e.g., reconstructed from Vault)\n\tca, cert, key, errMsg, ok := getClientConfigurationValues(ctx, objValue)\n\n\tif !ok {\n\t\tt.Fatalf(\"Expected extraction to succeed, got error: %s\", errMsg)\n\t}\n\n\tif ca != \"vault-ca-cert\" {\n\t\tt.Errorf(\"Expected ca='vault-ca-cert', got '%s'\", ca)\n\t}\n\n\tif cert != \"vault-client-cert\" {\n\t\tt.Errorf(\"Expected cert='vault-client-cert', got '%s'\", cert)\n\t}\n\n\tif key != \"vault-client-key\" {\n\t\tt.Errorf(\"Expected key='vault-client-key', got '%s'\", key)\n\t}\n}\n\n// TestGetClientConfigurationValues_Null tests that null values are handled correctly.\nfunc TestGetClientConfigurationValues_Null(t *testing.T) {\n\tt.Parallel()\n\n\tctx := context.Background()\n\n\tobjValue := basetypes.NewObjectNull(map[string]attr.Type{\n\t\t\"ca_certificate\":     types.StringType,\n\t\t\"client_certificate\": types.StringType,\n\t\t\"client_key\":         types.StringType,\n\t})\n\n\tca, cert, key, errMsg, ok := getClientConfigurationValues(ctx, objValue)\n\n\tif ok {\n\t\tt.Fatal(\"Expected extraction to fail for null value\")\n\t}\n\n\tif errMsg == \"\" {\n\t\tt.Error(\"Expected error message for null value\")\n\t}\n\n\tif ca != \"\" || cert != \"\" || key != \"\" {\n\t\tt.Error(\"Expected empty strings for null value\")\n\t}\n}\n\n// TestGetClientConfigurationValues_Unknown tests that unknown values are handled correctly.\nfunc TestGetClientConfigurationValues_Unknown(t *testing.T) {\n\tt.Parallel()\n\n\tctx := context.Background()\n\n\tobjValue := basetypes.NewObjectUnknown(map[string]attr.Type{\n\t\t\"ca_certificate\":     types.StringType,\n\t\t\"client_certificate\": types.StringType,\n\t\t\"client_key\":         types.StringType,\n\t})\n\n\tca, cert, key, errMsg, ok := getClientConfigurationValues(ctx, objValue)\n\n\tif ok {\n\t\tt.Fatal(\"Expected extraction to fail for unknown value\")\n\t}\n\n\tif errMsg == \"\" {\n\t\tt.Error(\"Expected error message for unknown value\")\n\t}\n\n\tif ca != \"\" || cert != \"\" || key != \"\" {\n\t\tt.Error(\"Expected empty strings for unknown value\")\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/generate_kubeconfig_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/siderolabs/talos/pkg/machinery/config/generate/secrets\"\n\n\t\"github.com/siderolabs/terraform-provider-talos/pkg/talos\"\n)\n\n// TestGenerateKubeconfigDeterminism calls GenerateKubeconfig twice with\n// identical inputs and asserts the output is byte-identical. This test\n// fails if the implementation uses non-deterministic randomness (e.g.\n// crypto/rand) for key generation or certificate serial numbers.\nfunc TestGenerateKubeconfigDeterminism(t *testing.T) {\n\tfixedTime := time.Date(2024, 6, 15, 0, 0, 0, 0, time.UTC)\n\n\tbundle, err := secrets.NewBundle(secrets.NewFixedClock(fixedTime), nil)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create secrets bundle: %v\", err)\n\t}\n\n\tclusterName := \"determinism-test\"\n\tendpoint := \"https://10.0.0.1:6443\"\n\tnotBefore := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)\n\tnotAfter := notBefore.Add(87600 * time.Hour)\n\n\tfirst, err := talos.GenerateKubeconfig(bundle, clusterName, endpoint, notBefore, notAfter)\n\tif err != nil {\n\t\tt.Fatalf(\"first GenerateKubeconfig failed: %v\", err)\n\t}\n\n\tsecond, err := talos.GenerateKubeconfig(bundle, clusterName, endpoint, notBefore, notAfter)\n\tif err != nil {\n\t\tt.Fatalf(\"second GenerateKubeconfig failed: %v\", err)\n\t}\n\n\tif first.Raw != second.Raw {\n\t\tt.Errorf(\"GenerateKubeconfig is not deterministic: two calls with identical inputs produced different output (%d vs %d bytes)\", len(first.Raw), len(second.Raw))\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/internal/gen/diskspec.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n//go:build exclude\n\npackage main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"go/format\"\n\t\"log\"\n\t\"os\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/siderolabs/talos/pkg/machinery/resources/block\"\n)\n\nfunc resourceMaps() map[string]any {\n\treturn map[string]any{\n\t\t\"block.DiskSpec\": block.DiskSpec{},\n\t}\n}\n\nfunc main() {\n\tvar g Generator\n\n\tg.Printf(\"// This Source Code Form is subject to the terms of the Mozilla Public\\n\")\n\tg.Printf(\"// License, v. 2.0. If a copy of the MPL was not distributed with this\\n\")\n\tg.Printf(\"// file, You can obtain one at http://mozilla.org/MPL/2.0/.\\n\\n\")\n\n\tg.Printf(\"// Code generated by \\\"diskspec.go\\\"; DO NOT EDIT.\\n\")\n\tg.Printf(\"\\n\")\n\tg.Printf(\"package talos\\n\")\n\tg.Printf(\"\\n\")\n\tg.Printf(\"import (\\n\")\n\tg.Printf(\"\\t\\\"github.com/hashicorp/terraform-plugin-framework/attr\\\"\\n\")\n\tg.Printf(\"\\t\\\"github.com/hashicorp/terraform-plugin-framework/datasource/schema\\\"\\n\")\n\tg.Printf(\"\\t\\\"github.com/hashicorp/terraform-plugin-framework/types\\\"\\n\")\n\tg.Printf(\"\\t\\\"github.com/siderolabs/gen/xslices\\\"\\n\")\n\tg.Printf(\"\\t\\\"github.com/siderolabs/talos/pkg/machinery/resources/block\\\"\\n\")\n\tg.Printf(\")\")\n\tg.Printf(\"\\n\")\n\n\tif len(os.Args) < 3 {\n\t\tlog.Fatalf(\"usage: %s <type> <resource name>\", os.Args[0])\n\t}\n\n\tresourceType := os.Args[1]\n\tresourceName := strings.ToLower(strings.Split(resourceType, \".\")[1])\n\n\tresource, ok := resourceMaps()[resourceType]\n\tif !ok {\n\t\tlog.Fatalf(\"unknown type: %s\", resourceType)\n\t}\n\n\tblockDiskSpecStruct := reflect.TypeOf(resource)\n\n\tg.Printf(\"type %s struct {\\n\", resourceName)\n\tfor i := range blockDiskSpecStruct.NumField() {\n\t\ttfType, err := mapGoTypesToTFTypes(blockDiskSpecStruct.Field(i).Type)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"failed to map type %s: %v\", blockDiskSpecStruct.Field(i).Type.Name(), err)\n\t\t}\n\n\t\tg.Printf(\"\\t%s %s `tfsdk:\\\"%s\\\"`\\n\",\n\t\t\tblockDiskSpecStruct.Field(i).Name,\n\t\t\ttfType,\n\t\t\tstrings.ReplaceAll(blockDiskSpecStruct.Field(i).Tag.Get(\"yaml\"), \",omitempty\", \"\"),\n\t\t)\n\n\t}\n\tg.Printf(\"}\\n\")\n\tg.Printf(\"\\n\")\n\n\tg.Printf(\"var %sAttributes = map[string]schema.Attribute{\\n\", resourceName)\n\tfor i := 0; i < blockDiskSpecStruct.NumField(); i++ {\n\t\tattributeType, err := mapGoTypesToTFAttributeSpec(blockDiskSpecStruct.Field(i).Type)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"failed to map type %s: %v\", blockDiskSpecStruct.Field(i).Type.Name(), err)\n\t\t}\n\n\t\tg.Printf(\"\\t\\\"%s\\\": %s,\\n\",\n\t\t\tstrings.ReplaceAll(blockDiskSpecStruct.Field(i).Tag.Get(\"yaml\"), \",omitempty\", \"\"),\n\t\t\tattributeType,\n\t\t)\n\t}\n\tg.Printf(\"}\\n\")\n\n\tg.Printf(\"func %sToTFTypes(%sSpec %s) %s {\\n\", resourceName, resourceName, resourceType, resourceName)\n\tg.Printf(\"\\treturn %s{\\n\", resourceName)\n\n\tfor i := 0; i < blockDiskSpecStruct.NumField(); i++ {\n\t\ttfType, err := mapStructTypeToTFType(blockDiskSpecStruct.Field(i), resourceName)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"failed to map type %s: %v\", blockDiskSpecStruct.Field(i).Type.Name(), err)\n\t\t}\n\n\t\tg.Printf(\"\\t\\t%s: %s,\\n\",\n\t\t\tblockDiskSpecStruct.Field(i).Name,\n\t\t\ttfType,\n\t\t)\n\t}\n\n\tg.Printf(\"\\t}\\n\")\n\tg.Printf(\"}\\n\")\n\n\tsrc := g.format()\n\n\tif err := os.WriteFile(fmt.Sprintf(\"%s_types.go\", os.Args[2]), src, 0o644); err != nil {\n\t\tlog.Fatalf(\"failed to write file: %v\", err)\n\t}\n}\n\ntype Generator struct {\n\tbuf bytes.Buffer\n}\n\nfunc (g *Generator) Printf(format string, args ...interface{}) {\n\tfmt.Fprintf(&g.buf, format, args...)\n}\n\n// format returns the gofmt-ed contents of the Generator's buffer.\nfunc (g *Generator) format() []byte {\n\tsrc, err := format.Source(g.buf.Bytes())\n\tif err != nil {\n\t\t// Should never happen, but can arise when developing this code.\n\t\t// The user can compile the output to see the error.\n\t\tlog.Printf(\"warning: internal error: invalid Go generated: %s\", err)\n\t\tlog.Printf(\"warning: compile the package to analyze the error\")\n\t\treturn g.buf.Bytes()\n\t}\n\n\treturn src\n}\n\nfunc mapGoTypesToTFTypes(goType reflect.Type) (string, error) {\n\t// handle the case where the field is a slice\n\tif goType.Kind() == reflect.Slice {\n\t\tswitch goType.Elem().Kind() {\n\t\tcase reflect.String:\n\t\t\treturn \"types.List\", nil\n\t\tdefault:\n\t\t\treturn \"\", fmt.Errorf(\"unsupported slice type: %s\", goType.Elem().Name())\n\t\t}\n\t}\n\n\tswitch goType.Name() {\n\tcase \"string\":\n\t\treturn \"types.String\", nil\n\tcase \"uint\", \"uint64\", \"int\", \"int64\":\n\t\treturn \"types.Int64\", nil\n\tcase \"bool\":\n\t\treturn \"types.Bool\", nil\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"unsupported type: %s\", goType.Name())\n\t}\n}\n\nfunc mapGoTypesToTFAttributeSpec(goType reflect.Type) (string, error) {\n\t// handle the case where the field is a slice\n\tif goType.Kind() == reflect.Slice {\n\t\tswitch goType.Elem().Kind() {\n\t\tcase reflect.String:\n\t\t\treturn `schema.ListAttribute{\n\tElementType: types.StringType,\n\tComputed:    true,\n\t}`, nil\n\t\tdefault:\n\t\t\treturn \"\", fmt.Errorf(\"unsupported slice type: %s\", goType.Elem().Name())\n\t\t}\n\t}\n\n\tswitch goType.Name() {\n\tcase \"string\":\n\t\treturn `schema.StringAttribute{\n\tComputed: true,\n\t}`, nil\n\tcase \"uint\", \"uint64\", \"int\", \"int64\":\n\t\treturn `schema.Int64Attribute{\n\tComputed: true,\n\t}`, nil\n\tcase \"bool\":\n\t\treturn `schema.BoolAttribute{\n\tComputed: true,\n\t}`, nil\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"unsupported type: %s\", goType.Name())\n\t}\n}\n\nfunc mapStructTypeToTFType(structField reflect.StructField, resourceName string) (string, error) {\n\t// handle the case where the field is a slice\n\tif structField.Type.Kind() == reflect.Slice {\n\t\tswitch structField.Type.Elem().Kind() {\n\t\tcase reflect.String:\n\t\t\treturn fmt.Sprintf(`types.ListValueMust(types.StringType, xslices.Map(%sSpec.%s, func(s string) attr.Value {\n\t\t\treturn types.StringValue(s)\n\t\t}))`, resourceName, structField.Name), nil\n\t\tdefault:\n\t\t\treturn \"\", fmt.Errorf(\"unsupported slice type: %s\", structField.Type.Elem().Name())\n\t\t}\n\t}\n\n\tswitch structField.Type.Name() {\n\tcase \"string\":\n\t\treturn fmt.Sprintf(\"types.StringValue(%sSpec.%s)\", resourceName, structField.Name), nil\n\tcase \"uint\", \"uint64\", \"int\", \"int64\":\n\t\treturn fmt.Sprintf(\"types.Int64Value(int64(%sSpec.%s))\", resourceName, structField.Name), nil\n\tcase \"bool\":\n\t\treturn fmt.Sprintf(\"types.BoolValue(%sSpec.%s)\", resourceName, structField.Name), nil\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"unsupported type: %s\", structField.Type.Name())\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/provider.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n// Package talos is a Terraform provider for Talos.\npackage talos\n\nimport (\n\t\"context\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/ephemeral\"\n\t\"github.com/hashicorp/terraform-plugin-framework/provider\"\n\t\"github.com/hashicorp/terraform-plugin-framework/provider/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/siderolabs/image-factory/pkg/client\"\n)\n\nconst (\n\t// ImageFactoryURL is the default URL of Image Factory.\n\tImageFactoryURL = \"https://factory.talos.dev\"\n)\n\n// talosProvider is the provider implementation.\ntype talosProvider struct{}\n\ntype talosProviderModelV0 struct {\n\tImageFactoryURL types.String `tfsdk:\"image_factory_url\"`\n}\n\n// New is a helper function to simplify provider server and testing implementation.\nfunc New() provider.Provider {\n\treturn &talosProvider{}\n}\n\n// Metadata returns the provider type name.\nfunc (p *talosProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {\n\tresp.TypeName = \"talos\"\n}\n\n// Schema defines the provider-level schema for configuration data.\nfunc (p *talosProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"image_factory_url\": schema.StringAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"The URL of Image Factory to generate schematics. If not set defaults to https://factory.talos.dev.\",\n\t\t\t},\n\t\t},\n\t}\n}\n\n// Configure prepares a Talos client for data sources and resources.\nfunc (p *talosProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {\n\tvar config talosProviderModelV0\n\n\tresp.Diagnostics.Append(req.Config.Get(ctx, &config)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\timageFactoryURL := config.ImageFactoryURL.ValueString()\n\n\tif imageFactoryURL == \"\" && !config.ImageFactoryURL.IsUnknown() {\n\t\timageFactoryURL = ImageFactoryURL\n\t}\n\n\timageFactoryClient, err := client.New(imageFactoryURL)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to create Image Factory client\", err.Error())\n\n\t\treturn\n\t}\n\n\tresp.DataSourceData = imageFactoryClient\n\tresp.ResourceData = imageFactoryClient\n}\n\n// DataSources defines the data sources implemented in the provider.\nfunc (p *talosProvider) DataSources(_ context.Context) []func() datasource.DataSource {\n\treturn []func() datasource.DataSource{\n\t\tNewTalosMachineDisksDataSource,\n\t\tNewTalosMachineConfigurationDataSource,\n\t\tNewTalosClientConfigurationDataSource,\n\t\tNewTalosClusterHealthDataSource,\n\t\tNewTalosClusterKubeConfigDataSource,\n\t\tNewTalosImageFactoryVersionsDataSource,\n\t\tNewTalosImageFactoryExtensionsVersionsDataSource,\n\t\tNewTalosImageFactoryOverlaysVersionsDataSource,\n\t\tNewTalosImageFactoryURLSDataSource,\n\t}\n}\n\n// Resources defines the resources implemented in the provider.\nfunc (p *talosProvider) Resources(_ context.Context) []func() resource.Resource {\n\treturn []func() resource.Resource{\n\t\tNewTalosMachineSecretsResource,\n\t\tNewTalosMachineConfigurationApplyResource,\n\t\tNewTalosMachineBootstrapResource,\n\t\tNewTalosClusterKubeConfigResource,\n\t\tNewTalosImageFactorySchematicResource,\n\t}\n}\n\n// EphemeralResources defines the ephemeral resources implemented in the provider.\nfunc (p *talosProvider) EphemeralResources(_ context.Context) []func() ephemeral.EphemeralResource {\n\treturn []func() ephemeral.EphemeralResource{\n\t\tNewTalosMachineSecretsEphemeralResource,\n\t\tNewTalosMachineConfigurationEphemeralResource,\n\t\tNewTalosClientConfigurationEphemeralResource,\n\t\tNewTalosClusterKubeConfigEphemeralResource,\n\t\tNewTalosClusterHealthEphemeralResource,\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/provider_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"text/template\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework/providerserver\"\n\t\"github.com/hashicorp/terraform-plugin-go/tfprotov6\"\n\t\"github.com/siderolabs/talos/pkg/machinery/gendata\"\n\n\t\"github.com/siderolabs/terraform-provider-talos/pkg/talos\"\n)\n\n// testAccProtoV6ProviderFactories are used to instantiate a provider during\n// acceptance testing. The factory function will be invoked for every Terraform\n// CLI command executed to create a provider server to which the CLI can\n// reattach.\nvar testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){\n\t\"talos\": providerserver.NewProtocol6WithError(talos.New()),\n}\n\ntype dynamicConfig struct {\n\tProvider               string\n\tResourceName           string\n\tIsoURL                 string\n\tCPUMode                string\n\tWithApplyConfig        bool\n\tWithBootstrap          bool\n\tWithRetrieveKubeConfig bool\n\tWithClusterHealth      bool\n}\n\nconst (\n\tcpuModeHostPassthrough = \"host-passthrough\"\n\tcpuModeHostModel       = \"host-model\"\n)\n\nfunc (c *dynamicConfig) render() string {\n\tcpuMode := cpuModeHostPassthrough\n\tif os.Getenv(\"CI\") != \"\" {\n\t\tcpuMode = cpuModeHostModel\n\t}\n\n\tc.CPUMode = cpuMode\n\n\tc.IsoURL = fmt.Sprintf(\"https://github.com/siderolabs/talos/releases/download/%s/metal-amd64.iso\", gendata.VersionTag)\n\n\tconfigTemplate := `\nresource \"talos_machine_secrets\" \"this\" {}\n\nresource \"libvirt_volume\" \"cp\" {\n  name = \"{{ .ResourceName }}\"\n  size = 6442450944\n}\n\nresource \"libvirt_domain\" \"cp\" {\n  name     = \"{{ .ResourceName }}\"\n  firmware = \"/usr/share/OVMF/OVMF_CODE_4M.fd\"\n  lifecycle {\n    ignore_changes = [\n      cpu,\n      nvram,\n      disk[\"url\"],\n      firmware,\n    ]\n  }\n  cpu {\n    mode = \"{{ .CPUMode }}\"\n  }\n  console {\n    type        = \"pty\"\n    target_port = \"0\"\n  }\n  graphics {\n    type        = \"vnc\"\n    listen_type = \"address\"\n  }\n  disk {\n    url = \"{{ .IsoURL }}\"\n  }\n  disk {\n    volume_id = libvirt_volume.cp.id\n  }\n  boot_device {\n    dev = [\"cdrom\"]\n  }\n  network_interface {\n    network_name   = \"default\"\n    wait_for_lease = true\n  }\n  vcpu   = \"2\"\n  memory = \"4096\"\n}\n\n{{ if eq .Provider \"talosv1\"}}\nresource \"talos_client_configuration\" \"this\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_controlplane\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  cluster_endpoint = \"https://${libvirt_domain.cp.network_interface[0].addresses[0]}:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\n{{ if .WithApplyConfig }}\nresource \"talos_machine_configuration_apply\" \"this\" {\n  talos_config          = talos_client_configuration.this.talos_config\n  machine_configuration = talos_machine_configuration_controlplane.this.machine_config\n  node                  = libvirt_domain.cp.network_interface[0].addresses[0]\n  endpoint              = libvirt_domain.cp.network_interface[0].addresses[0]\n  config_patches = [\n    yamlencode({\n      machine = {\n        install = {\n          disk = \"/dev/vda\"\n        }\n      }\n    }),\n  ]\n}\n{{ end }}\n\n{{ if .WithBootstrap }}\nresource \"talos_machine_bootstrap\" \"this\" {\n  depends_on = [\n    talos_machine_configuration_apply.this\n  ]\n  node         = libvirt_domain.cp.network_interface[0].addresses[0]\n  endpoint     = libvirt_domain.cp.network_interface[0].addresses[0]\n  talos_config = talos_client_configuration.this.talos_config\n}\n{{ end }}\n{{ else }}\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  cluster_endpoint = \"https://${libvirt_domain.cp.network_interface[0].addresses[0]}:6443\"\n  machine_type     = \"controlplane\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n  docs             = false\n  examples         = false\n}\n\ndata \"talos_machine_disks\" \"this\" {\n  client_configuration = talos_machine_secrets.this.client_configuration\n  node                 = libvirt_domain.cp.network_interface[0].addresses[0]\n  selector             = \"disk.size > 6u * GB\"\n}\n\n{{ if .WithApplyConfig }}\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = libvirt_domain.cp.network_interface[0].addresses[0]\n  config_patches = [\n    yamlencode({\n      machine = {\n        install = {\n          disk = data.talos_machine_disks.this.disks[0].dev_path\n        }\n      }\n    }),\n  ]\n}\n{{ end }}\n\n{{ if .WithBootstrap }}\nresource \"talos_machine_bootstrap\" \"this\" {\n  depends_on = [\n    talos_machine_configuration_apply.this\n  ]\n  node                 = libvirt_domain.cp.network_interface[0].addresses[0]\n  client_configuration = talos_machine_secrets.this.client_configuration\n}\n{{ end }}\n\n{{ if .WithRetrieveKubeConfig }}\nresource \"talos_cluster_kubeconfig\" \"this\" {\n  depends_on = [\n    talos_machine_bootstrap.this\n  ]\n  client_configuration = talos_machine_secrets.this.client_configuration\n  node                 = libvirt_domain.cp.network_interface[0].addresses[0]\n}\n{{ end }}\n\n{{ if .WithClusterHealth }}\ndata \"talos_cluster_health\" \"this\" {\n  depends_on = [\n    talos_cluster_kubeconfig.this\n  ]\n\n  timeouts = {\n    read = \"25m\"\n  }\n\n  client_configuration = talos_machine_secrets.this.client_configuration\n  endpoints            = libvirt_domain.cp.network_interface[0].addresses\n  control_plane_nodes  = libvirt_domain.cp.network_interface[0].addresses\n}\n{{ end }}\n{{ end }}\n`\n\n\tvar config strings.Builder\n\n\ttemplate.Must(template.New(\"tf_config\").Parse(configTemplate)).Execute(&config, c) //nolint:errcheck\n\n\treturn config.String()\n}\n"
  },
  {
    "path": "pkg/talos/rfc6979.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\n// RFC 6979 deterministic ECDSA nonce generation for P-256.\n// This produces signatures that are fully deterministic (no randomness),\n// which is required because Go 1.26+ ignores custom io.Reader in crypto/ecdsa.\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/hmac\"\n\t\"crypto/sha256\"\n\t\"encoding/asn1\"\n\t\"io\"\n\t\"math/big\"\n)\n\n// deterministicECDSASigner wraps an ECDSA private key and produces RFC 6979\n// deterministic signatures instead of using random nonces.\ntype deterministicECDSASigner struct {\n\tkey *ecdsa.PrivateKey\n}\n\nfunc (s *deterministicECDSASigner) Public() crypto.PublicKey {\n\treturn &s.key.PublicKey\n}\n\nfunc (s *deterministicECDSASigner) Sign(_ io.Reader, digest []byte, _ crypto.SignerOpts) ([]byte, error) {\n\tr, ss := rfc6979Sign(s.key, digest)\n\n\treturn asn1.Marshal(struct {\n\t\tR, S *big.Int\n\t}{r, ss})\n}\n\n// rfc6979Sign computes an ECDSA signature using the deterministic nonce\n// generation algorithm from RFC 6979, Section 3.2.\nfunc rfc6979Sign(key *ecdsa.PrivateKey, hash []byte) (*big.Int, *big.Int) {\n\tcurve := key.Curve\n\tn := curve.Params().N\n\tqLen := (n.BitLen() + 7) / 8 // byte length of the curve order\n\n\t// Use Bytes() instead of the deprecated D field.\n\t// Bytes never returns an error for valid keys.\n\tkeyBytes, _ := key.Bytes() //nolint:errcheck\n\td := new(big.Int).SetBytes(keyBytes)\n\n\t// int2octets: private key as a fixed-length big-endian integer.\n\tx := keyBytes\n\n\t// bits2octets: reduce hash modulo n, then encode as fixed-length.\n\th1 := bits2octets(hash, n, qLen)\n\n\t// Section 3.2 steps a-f: initialize HMAC_DRBG.\n\thLen := sha256.Size // 32 for SHA-256\n\tv := make([]byte, hLen)\n\tk := make([]byte, hLen)\n\n\tfor i := range v {\n\t\tv[i] = 0x01\n\t}\n\n\t// Step d: K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1))\n\tk = hmacSHA256(k, v, []byte{0x00}, x, h1)\n\t// Step e: V = HMAC_K(V)\n\tv = hmacSHA256(k, v)\n\t// Step f: K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1))\n\tk = hmacSHA256(k, v, []byte{0x01}, x, h1)\n\t// Step g: V = HMAC_K(V)\n\tv = hmacSHA256(k, v)\n\n\t// Step h: generate k candidates until valid.\n\tfor {\n\t\t// For P-256 with SHA-256, one HMAC output (32 bytes) = qLen.\n\t\tv = hmacSHA256(k, v)\n\t\tkCandidate := bits2int(v, n)\n\n\t\tif kCandidate.Sign() > 0 && kCandidate.Cmp(n) < 0 {\n\t\t\tr, ss := rawECDSASign(curve, n, d, kCandidate, hash)\n\t\t\tif r.Sign() > 0 && ss.Sign() > 0 {\n\t\t\t\treturn r, ss\n\t\t\t}\n\t\t}\n\n\t\t// Not valid, update K and V per RFC 6979 step h.3.\n\t\tk = hmacSHA256(k, v, []byte{0x00})\n\t\tv = hmacSHA256(k, v)\n\t}\n}\n\n// rawECDSASign computes (r, s) given a nonce k, following the standard ECDSA\n// signature algorithm.\nfunc rawECDSASign(curve elliptic.Curve, n, d, k *big.Int, hash []byte) (*big.Int, *big.Int) {\n\t// R = k * G\n\t// No non-deprecated API exposes the x-coordinate of a scalar multiplication.\n\trx, _ := curve.ScalarBaseMult(k.Bytes()) //nolint:staticcheck\n\tr := new(big.Int).Mod(rx, n)\n\n\tif r.Sign() == 0 {\n\t\treturn r, new(big.Int)\n\t}\n\n\t// s = k^-1 * (hash + r * d) mod n\n\te := bits2int(hash, n)\n\ts := new(big.Int).Mul(r, d)\n\ts.Add(s, e)\n\n\tkInv := new(big.Int).ModInverse(k, n)\n\ts.Mul(s, kInv)\n\ts.Mod(s, n)\n\n\treturn r, s\n}\n\n// hmacSHA256 computes HMAC-SHA256(key, data...).\nfunc hmacSHA256(key []byte, data ...[]byte) []byte {\n\th := hmac.New(sha256.New, key)\n\tfor _, d := range data {\n\t\th.Write(d) //nolint:errcheck\n\t}\n\n\treturn h.Sum(nil)\n}\n\n// int2octets converts a big.Int to a fixed-length (qLen) big-endian byte slice.\nfunc int2octets(v *big.Int, qLen int) []byte {\n\tout := v.Bytes()\n\tif len(out) >= qLen {\n\t\treturn out[:qLen]\n\t}\n\n\tpadded := make([]byte, qLen)\n\tcopy(padded[qLen-len(out):], out)\n\n\treturn padded\n}\n\n// bits2int interprets a byte slice as a big-endian integer and reduces to\n// the bit length of n.\nfunc bits2int(b []byte, n *big.Int) *big.Int {\n\tv := new(big.Int).SetBytes(b)\n\texcess := len(b)*8 - n.BitLen()\n\n\tif excess > 0 {\n\t\tv.Rsh(v, uint(excess))\n\t}\n\n\treturn v\n}\n\n// bits2octets converts a hash to a fixed-length byte slice reduced modulo n.\nfunc bits2octets(hash []byte, n *big.Int, qLen int) []byte {\n\tz := bits2int(hash, n)\n\tif z.Cmp(n) >= 0 {\n\t\tz.Sub(z, n)\n\t}\n\n\treturn int2octets(z, qLen)\n}\n"
  },
  {
    "path": "pkg/talos/rfc6979_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos //nolint:testpackage\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"math/big\"\n\t\"testing\"\n)\n\n// TestRFC6979SignTestVectors validates the RFC 6979 implementation against\n// the official test vectors from RFC 6979 Appendix A.2.5 (ECDSA P-256 / SHA-256).\nfunc TestRFC6979SignTestVectors(t *testing.T) {\n\tt.Parallel()\n\n\t// Private key from RFC 6979 A.2.5.\n\txHex := \"C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721\"\n\n\txBytes, err := hex.DecodeString(xHex)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to decode test private key hex: %v\", err)\n\t}\n\n\tkey, err := ecdsa.ParseRawPrivateKey(elliptic.P256(), xBytes)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to parse test private key: %v\", err)\n\t}\n\n\ttests := []struct {\n\t\tname      string\n\t\tmessage   string\n\t\texpectedR string\n\t\texpectedS string\n\t}{\n\t\t{\n\t\t\tname:      \"sample\",\n\t\t\tmessage:   \"sample\",\n\t\t\texpectedR: \"EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716\",\n\t\t\texpectedS: \"F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8\",\n\t\t},\n\t\t{\n\t\t\tname:      \"test\",\n\t\t\tmessage:   \"test\",\n\t\t\texpectedR: \"F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367\",\n\t\t\texpectedS: \"019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083\",\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\thash := sha256.Sum256([]byte(tc.message))\n\t\t\tr, s := rfc6979Sign(key, hash[:])\n\n\t\t\texpectedR, _ := new(big.Int).SetString(tc.expectedR, 16)\n\t\t\texpectedS, _ := new(big.Int).SetString(tc.expectedS, 16)\n\n\t\t\tif r.Cmp(expectedR) != 0 {\n\t\t\t\tt.Errorf(\"r mismatch for %q:\\n  got:  %064X\\n  want: %064X\", tc.message, r, expectedR)\n\t\t\t}\n\n\t\t\tif s.Cmp(expectedS) != 0 {\n\t\t\t\tt.Errorf(\"s mismatch for %q:\\n  got:  %064X\\n  want: %064X\", tc.message, s, expectedS)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_client_configuration_data_source.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/schema/validator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n)\n\ntype talosClientConfigurationDataSource struct{}\n\ntype talosClientConfigurationDataSourceModelV0 struct {\n\tID                  types.String        `tfsdk:\"id\"`\n\tClusterName         types.String        `tfsdk:\"cluster_name\"`\n\tClientConfiguration clientConfiguration `tfsdk:\"client_configuration\"`\n\tEndpoints           types.List          `tfsdk:\"endpoints\"`\n\tNodes               types.List          `tfsdk:\"nodes\"`\n\tTalosConfig         types.String        `tfsdk:\"talos_config\"`\n}\n\nvar _ datasource.DataSource = &talosClientConfigurationDataSource{}\n\n// NewTalosClientConfigurationDataSource implements the datasource.DataSource interface.\nfunc NewTalosClientConfigurationDataSource() datasource.DataSource {\n\treturn &talosClientConfigurationDataSource{}\n}\n\nfunc (d *talosClientConfigurationDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_client_configuration\"\n}\n\nfunc (d *talosClientConfigurationDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"Generate client configuration for a Talos cluster\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tDescription: \"The ID of this resource\",\n\t\t\t\tComputed:    true,\n\t\t\t},\n\t\t\t\"cluster_name\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The name of the cluster in the generated config\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tstringvalidator.LengthAtLeast(1),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The client configuration data\",\n\t\t\t},\n\t\t\t\"endpoints\": schema.ListAttribute{\n\t\t\t\tElementType: types.StringType,\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"endpoints to set in the generated config\",\n\t\t\t},\n\t\t\t\"nodes\": schema.ListAttribute{\n\t\t\t\tElementType: types.StringType,\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"nodes to set in the generated config\",\n\t\t\t},\n\t\t\t\"talos_config\": schema.StringAttribute{\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The generated client configuration\",\n\t\t\t\tSensitive:   true,\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (d *talosClientConfigurationDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {\n\tvar state talosClientConfigurationDataSourceModelV0\n\n\tdiags := req.Config.Get(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar endpoints []string\n\n\tvar nodes []string\n\n\tresp.Diagnostics.Append(state.Endpoints.ElementsAs(ctx, &endpoints, true)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tresp.Diagnostics.Append(state.Nodes.ElementsAs(ctx, &nodes, true)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\ttalosConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\tstate.ClusterName.ValueString(),\n\t\tstate.ClientConfiguration.CA.ValueString(),\n\t\tstate.ClientConfiguration.Cert.ValueString(),\n\t\tstate.ClientConfiguration.Key.ValueString(),\n\t)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to generate talos config\", err.Error())\n\n\t\treturn\n\t}\n\n\tif len(endpoints) > 0 {\n\t\ttalosConfig.Contexts[state.ClusterName.ValueString()].Endpoints = endpoints\n\t}\n\n\tif len(nodes) > 0 {\n\t\ttalosConfig.Contexts[state.ClusterName.ValueString()].Nodes = nodes\n\t}\n\n\ttalosConfigStringBytes, err := talosConfig.Bytes()\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to generate talos config\", err.Error())\n\n\t\treturn\n\t}\n\n\tstate.TalosConfig = basetypes.NewStringValue(string(talosConfigStringBytes))\n\tstate.ID = state.ClusterName\n\n\tdiags = resp.State.Set(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_client_configuration_data_source_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\t\"text/template\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n\t\"github.com/siderolabs/talos/pkg/machinery/client/config\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"go.yaml.in/yaml/v4\"\n)\n\nfunc TestAccTalosClientConfigurationDataSource(t *testing.T) {\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t// test data source with default values\n\t\t\t{\n\t\t\t\tConfig: testAccTalosClientConfigurationDataSourceConfig(\"test-cluster\", nil, nil),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_client_configuration.this\", \"id\", \"test-cluster\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_client_configuration.this\", \"cluster_name\", \"test-cluster\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_client_configuration.this\", \"client_configuration.%\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_client_configuration.this\", \"endpoints.#\", \"0\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_client_configuration.this\", \"nodes.#\", \"0\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_client_configuration.this\", \"talos_config\"),\n\t\t\t\t\tresource.TestCheckResourceAttrWith(\"data.talos_client_configuration.this\", \"talos_config\", func(value string) error {\n\t\t\t\t\t\treturn validateTalosClientConfigContext(t, value, \"test-cluster\", nil, nil)\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// test data source with overrides\n\t\t\t{\n\t\t\t\tConfig: testAccTalosClientConfigurationDataSourceConfig(\"test-cluster-1\", []string{\"10.5.0.2\", \"10.5.0.3\"}, []string{\"10.5.0.4\"}),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_client_configuration.this\", \"id\", \"test-cluster-1\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_client_configuration.this\", \"cluster_name\", \"test-cluster-1\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_client_configuration.this\", \"client_configuration.%\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_client_configuration.this\", \"endpoints.0\", \"10.5.0.2\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_client_configuration.this\", \"endpoints.1\", \"10.5.0.3\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_client_configuration.this\", \"nodes.0\", \"10.5.0.4\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_client_configuration.this\", \"talos_config\"),\n\t\t\t\t\tresource.TestCheckResourceAttrWith(\"data.talos_client_configuration.this\", \"talos_config\", func(value string) error {\n\t\t\t\t\t\treturn validateTalosClientConfigContext(t, value, \"test-cluster-1\", []string{\"10.5.0.2\", \"10.5.0.3\"}, []string{\"10.5.0.4\"})\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosClientConfigurationDataSourceConfig(clusterName string, endpoints, nodes []string) string {\n\tconfigTemplate := `\nresource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_client_configuration\" \"this\" {\n\tcluster_name         = \"{{ .ClusterName }}\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n  {{if .Endpoints }}endpoints            = [{{- range .Endpoints }}\n    \"{{  . }}\",\n  {{- end }}\n  ]{{end }}\n  {{if .Nodes }}nodes                = [{{- range .Nodes }}\n    \"{{  . }}\",\n  {{- end }}\n  ]{{end }}\n}\n`\n\n\tvar config strings.Builder\n\n\ttemplate.Must(template.New(\"tf_config\").Parse(configTemplate)).Execute(&config, struct { //nolint:errcheck\n\t\tClusterName string\n\t\tEndpoints   []string\n\t\tNodes       []string\n\t}{\n\t\tClusterName: clusterName,\n\t\tEndpoints:   endpoints,\n\t\tNodes:       nodes,\n\t})\n\n\treturn config.String()\n}\n\nfunc validateTalosClientConfigContext(t *testing.T, tc, contextName string, endpoints, nodes []string) error {\n\tvar talosConfig config.Config\n\n\tif err := yaml.Unmarshal([]byte(tc), &talosConfig); err != nil {\n\t\treturn err\n\t}\n\n\tassert.Equal(t, contextName, talosConfig.Context)\n\n\tif endpoints != nil {\n\t\tassert.Equal(t, endpoints, talosConfig.Contexts[contextName].Endpoints)\n\t}\n\n\tif nodes != nil {\n\t\tassert.Equal(t, nodes, talosConfig.Contexts[contextName].Nodes)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/talos/talos_client_configuration_ephemeral_resource.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/ephemeral\"\n\t\"github.com/hashicorp/terraform-plugin-framework/ephemeral/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/schema/validator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n)\n\nvar _ ephemeral.EphemeralResource = &talosClientConfigurationEphemeralResource{}\n\ntype talosClientConfigurationEphemeralResource struct{}\n\ntype talosClientConfigurationEphemeralResourceModel struct {\n\tClusterName         types.String        `tfsdk:\"cluster_name\"`\n\tMachineSecrets      machineSecrets      `tfsdk:\"machine_secrets\"`\n\tNotBefore           types.String        `tfsdk:\"not_before\"`\n\tCrtTTL              types.String        `tfsdk:\"crt_ttl\"`\n\tEndpoints           types.List          `tfsdk:\"endpoints\"`\n\tNodes               types.List          `tfsdk:\"nodes\"`\n\tTalosConfig         types.String        `tfsdk:\"talos_config\"`\n\tClientConfiguration clientConfiguration `tfsdk:\"client_configuration\"`\n}\n\n// NewTalosClientConfigurationEphemeralResource implements the ephemeral.EphemeralResource interface.\nfunc NewTalosClientConfigurationEphemeralResource() ephemeral.EphemeralResource {\n\treturn &talosClientConfigurationEphemeralResource{}\n}\n\nfunc (r *talosClientConfigurationEphemeralResource) Metadata(_ context.Context, req ephemeral.MetadataRequest, resp *ephemeral.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_client_configuration\"\n}\n\nfunc (r *talosClientConfigurationEphemeralResource) Schema(_ context.Context, _ ephemeral.SchemaRequest, resp *ephemeral.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"Generate client configuration for a Talos cluster from machine secrets. \" +\n\t\t\t\"This is an ephemeral resource that does not persist secrets in Terraform state. \" +\n\t\t\t\"The admin client certificate is generated with pinned timestamps so talos_config \" +\n\t\t\t\"is byte-identical on every open as long as machine_secrets and not_before are unchanged.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"cluster_name\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The name of the cluster in the generated config\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tstringvalidator.LengthAtLeast(1),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"machine_secrets\": machineSecretsSchemaAttribute(),\n\t\t\t\"not_before\": schema.StringAttribute{\n\t\t\t\tOptional: true,\n\t\t\t\tDescription: \"RFC3339 timestamp to use as the NotBefore field of the generated admin client certificate. \" +\n\t\t\t\t\t\"When set, the certificate validity starts at this time and ends at not_before + crt_ttl. \" +\n\t\t\t\t\t\"Persist this value in a terraform_data resource so it is stable across plans and the \" +\n\t\t\t\t\t\"generated talos_config is byte-identical on every open. \" +\n\t\t\t\t\t\"When omitted, the certificate uses the OS CA's own NotBefore/NotAfter timestamps.\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\trfc3339Valid(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"crt_ttl\": schema.StringAttribute{\n\t\t\t\tOptional: true,\n\t\t\t\tDescription: \"The lifetime of the generated admin client certificate as a Go duration string \" +\n\t\t\t\t\t\"(e.g. \\\"8760h\\\" for 1 year, \\\"87600h\\\" for 10 years). Defaults to \\\"87600h\\\" (10 years). \" +\n\t\t\t\t\t\"Only used when not_before is set; when not_before is omitted the cert uses the OS CA's NotAfter directly.\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tgoDurationValid(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"endpoints\": schema.ListAttribute{\n\t\t\t\tElementType: types.StringType,\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"endpoints to set in the generated config\",\n\t\t\t},\n\t\t\t\"nodes\": schema.ListAttribute{\n\t\t\t\tElementType: types.StringType,\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"nodes to set in the generated config\",\n\t\t\t},\n\t\t\t\"talos_config\": schema.StringAttribute{\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The generated client configuration\",\n\t\t\t\tSensitive:   true,\n\t\t\t},\n\t\t\t\"client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tComputed:    true,\n\t\t\t\tSensitive:   true,\n\t\t\t\tDescription: \"The generated client configuration data\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (r *talosClientConfigurationEphemeralResource) Open(ctx context.Context, req ephemeral.OpenRequest, resp *ephemeral.OpenResponse) {\n\tvar obj types.Object\n\n\tdiags := req.Config.Get(ctx, &obj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar config talosClientConfigurationEphemeralResourceModel\n\n\tdiags = obj.As(ctx, &config, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar endpoints []string\n\n\tvar nodes []string\n\n\tresp.Diagnostics.Append(config.Endpoints.ElementsAs(ctx, &endpoints, true)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tresp.Diagnostics.Append(config.Nodes.ElementsAs(ctx, &nodes, true)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tsecretsBundle, err := machineSecretsToSecretsBundle(talosMachineSecretsResourceModelV1{\n\t\tMachineSecrets: config.MachineSecrets,\n\t})\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to convert machine secrets to secrets bundle\", err.Error())\n\n\t\treturn\n\t}\n\n\tnotBefore, notAfter, tsErr := resolveClientConfigTimestamps(config.NotBefore.ValueString(), config.CrtTTL.ValueString(), secretsBundle.Certs.OS.Crt)\n\tif tsErr != nil {\n\t\tresp.Diagnostics.AddError(tsErr.summary, tsErr.detail)\n\n\t\treturn\n\t}\n\n\tcc, err := generateClientConfiguration(secretsBundle, config.ClusterName.ValueString(), notBefore, notAfter)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to generate client configuration\", err.Error())\n\n\t\treturn\n\t}\n\n\ttalosConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\tconfig.ClusterName.ValueString(),\n\t\tcc.CA.ValueString(),\n\t\tcc.Cert.ValueString(),\n\t\tcc.Key.ValueString(),\n\t)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to generate talos config\", err.Error())\n\n\t\treturn\n\t}\n\n\tif len(endpoints) > 0 {\n\t\ttalosConfig.Contexts[config.ClusterName.ValueString()].Endpoints = endpoints\n\t}\n\n\tif len(nodes) > 0 {\n\t\ttalosConfig.Contexts[config.ClusterName.ValueString()].Nodes = nodes\n\t}\n\n\ttalosConfigStringBytes, err := talosConfig.Bytes()\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to serialize talos config\", err.Error())\n\n\t\treturn\n\t}\n\n\tresult := talosClientConfigurationEphemeralResourceModel{\n\t\tClusterName:         config.ClusterName,\n\t\tMachineSecrets:      config.MachineSecrets,\n\t\tNotBefore:           config.NotBefore,\n\t\tCrtTTL:              config.CrtTTL,\n\t\tEndpoints:           config.Endpoints,\n\t\tNodes:               config.Nodes,\n\t\tTalosConfig:         basetypes.NewStringValue(string(talosConfigStringBytes)),\n\t\tClientConfiguration: cc,\n\t}\n\n\tdiags = resp.Result.Set(ctx, &result)\n\tresp.Diagnostics.Append(diags...)\n}\n"
  },
  {
    "path": "pkg/talos/talos_client_configuration_ephemeral_resource_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"regexp\"\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n\t\"github.com/hashicorp/terraform-plugin-testing/knownvalue\"\n\t\"github.com/hashicorp/terraform-plugin-testing/plancheck\"\n\t\"github.com/hashicorp/terraform-plugin-testing/statecheck\"\n\t\"github.com/hashicorp/terraform-plugin-testing/tfjsonpath\"\n\t\"github.com/hashicorp/terraform-plugin-testing/tfversion\"\n)\n\n// TestAccTalosClientConfigurationEphemeralResourceFromMachineSecrets tests that the ephemeral\n// resource generates talos_config from machine_secrets.\nfunc TestAccTalosClientConfigurationEphemeralResourceFromMachineSecrets(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_client_configuration\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n\tendpoints       = [\"10.0.0.1\"]\n\tnodes           = [\"10.0.0.2\"]\n}\n\nprovider \"echo\" {\n\tdata = {\n\t\tcluster_name = ephemeral.talos_client_configuration.this.cluster_name\n\t\ttalos_config = ephemeral.talos_client_configuration.this.talos_config\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"talos_config\"), knownvalue.NotNull()),\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"cluster_name\"), knownvalue.StringExact(\"test-cluster\")),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosClientConfigurationEphemeralResourceCustomTTL tests that not_before + crt_ttl\n// are accepted and the resource opens without error.\nfunc TestAccTalosClientConfigurationEphemeralResourceCustomTTL(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_client_configuration\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n\tnot_before      = \"2024-01-01T00:00:00Z\"\n\tcrt_ttl         = \"8760h\"\n}\n\nprovider \"echo\" {\n\tdata = {\n\t\ttalos_config = ephemeral.talos_client_configuration.this.talos_config\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"talos_config\"), knownvalue.NotNull()),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosClientConfigurationEphemeralResourceCrtTTLInvalid tests that an invalid\n// crt_ttl value is rejected with an error.\nfunc TestAccTalosClientConfigurationEphemeralResourceCrtTTLInvalid(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_client_configuration\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n\tcrt_ttl         = \"not-a-duration\"\n}\n\nprovider \"echo\" {\n\tdata = {}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tExpectError: regexp.MustCompile(`invalid crt_ttl`),\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosClientConfigurationEphemeralResourceDeterminism tests that two opens with\n// identical inputs (CA-pinned, no not_before) produce byte-identical talos_config.\nfunc TestAccTalosClientConfigurationEphemeralResourceDeterminism(t *testing.T) {\n\tt.Parallel()\n\n\tcfg := `\nresource \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_client_configuration\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = talos_machine_secrets.this.machine_secrets\n\tendpoints       = [\"10.0.0.1\"]\n}\n\nprovider \"echo\" {\n\tdata = {\n\t\ttalos_config = ephemeral.talos_client_configuration.this.talos_config\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: cfg,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"talos_config\"), knownvalue.NotNull()),\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tConfig: cfg,\n\t\t\t\tConfigPlanChecks: resource.ConfigPlanChecks{\n\t\t\t\t\tPreApply: []plancheck.PlanCheck{\n\t\t\t\t\t\tplancheck.ExpectEmptyPlan(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosClientConfigurationEphemeralResourceDeterminismWithNotBefore tests that two\n// opens with a terraform_data-sourced not_before produce byte-identical talos_config.\nfunc TestAccTalosClientConfigurationEphemeralResourceDeterminismWithNotBefore(t *testing.T) {\n\tt.Parallel()\n\n\tcfg := `\nresource \"talos_machine_secrets\" \"this\" {}\n\nresource \"terraform_data\" \"client_config_nbf\" {\n\tinput = \"2024-01-01T00:00:00Z\"\n}\n\nephemeral \"talos_client_configuration\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = talos_machine_secrets.this.machine_secrets\n\tnot_before      = terraform_data.client_config_nbf.output\n\tcrt_ttl         = \"87600h\"\n}\n\nprovider \"echo\" {\n\tdata = {\n\t\ttalos_config = ephemeral.talos_client_configuration.this.talos_config\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: cfg,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"talos_config\"), knownvalue.NotNull()),\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tConfig: cfg,\n\t\t\t\tConfigPlanChecks: resource.ConfigPlanChecks{\n\t\t\t\t\tPreApply: []plancheck.PlanCheck{\n\t\t\t\t\t\tplancheck.ExpectEmptyPlan(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosClientConfigurationEphemeralResourceInvalidNotBefore tests that an invalid\n// not_before is rejected with an error.\nfunc TestAccTalosClientConfigurationEphemeralResourceInvalidNotBefore(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_client_configuration\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n\tnot_before      = \"not-a-timestamp\"\n}\n\nprovider \"echo\" {\n\tdata = {}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tExpectError: regexp.MustCompile(`invalid not_before`),\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosClientConfigurationEphemeralResourceClientConfigurationOutput tests that\n// client_configuration is populated with ca_certificate, client_certificate, and client_key.\nfunc TestAccTalosClientConfigurationEphemeralResourceClientConfigurationOutput(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_client_configuration\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n}\n\nprovider \"echo\" {\n\tdata = {\n\t\tca_certificate     = ephemeral.talos_client_configuration.this.client_configuration.ca_certificate\n\t\tclient_certificate = ephemeral.talos_client_configuration.this.client_configuration.client_certificate\n\t\tclient_key         = ephemeral.talos_client_configuration.this.client_configuration.client_key\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"ca_certificate\"), knownvalue.NotNull()),\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"client_certificate\"), knownvalue.NotNull()),\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"client_key\"), knownvalue.NotNull()),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "pkg/talos/talos_cluster_health_data_source.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/siderolabs/talos/pkg/cluster\"\n\t\"github.com/siderolabs/talos/pkg/cluster/check\"\n\t\"github.com/siderolabs/talos/pkg/conditions\"\n\t\"github.com/siderolabs/talos/pkg/machinery/client\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/machine\"\n)\n\ntype talosClusterHealthDataSource struct{}\n\nvar _ datasource.DataSource = &talosClusterHealthDataSource{}\n\ntype talosClusterHealthDataSourceModelV0 struct {\n\tID                   types.String        `tfsdk:\"id\"`\n\tEndpoints            types.List          `tfsdk:\"endpoints\"`\n\tControlPlaneNodes    types.List          `tfsdk:\"control_plane_nodes\"`\n\tWorkerNodes          types.List          `tfsdk:\"worker_nodes\"`\n\tClientConfiguration  clientConfiguration `tfsdk:\"client_configuration\"`\n\tTimeouts             timeouts.Value      `tfsdk:\"timeouts\"`\n\tSkipKubernetesChecks types.Bool          `tfsdk:\"skip_kubernetes_checks\"`\n}\n\ntype clusterNodes struct {\n\tnodesByType map[machine.Type][]cluster.NodeInfo\n\tnodes       []cluster.NodeInfo\n}\n\nfunc newClusterNodes(controlPlaneNodes, workerNodes []string) (*clusterNodes, error) {\n\tcontrolPlaneNodeInfos, err := cluster.IPsToNodeInfos(controlPlaneNodes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tworkerNodeInfos, err := cluster.IPsToNodeInfos(workerNodes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tnodesByType := make(map[machine.Type][]cluster.NodeInfo)\n\tnodesByType[machine.TypeControlPlane] = controlPlaneNodeInfos\n\tnodesByType[machine.TypeWorker] = workerNodeInfos\n\n\treturn &clusterNodes{\n\t\tnodes:       slices.Concat(controlPlaneNodeInfos, workerNodeInfos),\n\t\tnodesByType: nodesByType,\n\t}, nil\n}\n\n// Nodes returns cluster nodeinfos.\nfunc (c *clusterNodes) Nodes() []cluster.NodeInfo {\n\treturn c.nodes\n}\n\n// NodesByType returns cluster nodeinfos by type.\nfunc (c *clusterNodes) NodesByType(t machine.Type) []cluster.NodeInfo {\n\treturn c.nodesByType[t]\n}\n\ntype reporter struct {\n\tlastLine string\n\ts        strings.Builder\n}\n\nfunc newReporter() *reporter {\n\treturn &reporter{}\n}\n\n// Update implements the conditions.Reporter interface.\nfunc (r *reporter) Update(condition conditions.Condition) {\n\tif condition.String() != r.lastLine {\n\t\tfmt.Fprintf(&r.s, \"waiting for %s\\n\", condition.String())\n\t\tr.lastLine = condition.String()\n\t}\n}\n\n// String returns the string representation of the reporter.\nfunc (r *reporter) String() string {\n\treturn r.s.String()\n}\n\n// NewTalosClusterHealthDataSource implements the datasource.DataSource interface.\nfunc NewTalosClusterHealthDataSource() datasource.DataSource {\n\treturn &talosClusterHealthDataSource{}\n}\n\nfunc (d *talosClusterHealthDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_cluster_health\"\n}\n\nfunc (d *talosClusterHealthDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription:         \"Checks the health of a Talos cluster\",\n\t\tMarkdownDescription: \"Waits for the Talos cluster to be healthy. Can be used as a dependency before running other operations on the cluster.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tComputed: true,\n\t\t\t},\n\t\t\t\"endpoints\": schema.ListAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tElementType: types.StringType,\n\t\t\t\tDescription: \"endpoints to use for the health check client. Use at least one control plane endpoint.\",\n\t\t\t},\n\t\t\t\"control_plane_nodes\": schema.ListAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tElementType: types.StringType,\n\t\t\t\tDescription: \"List of control plane nodes to check for health.\",\n\t\t\t},\n\t\t\t\"worker_nodes\": schema.ListAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tElementType: types.StringType,\n\t\t\t\tDescription: \"List of worker nodes to check for health.\",\n\t\t\t},\n\t\t\t\"skip_kubernetes_checks\": schema.BoolAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"Skip Kubernetes component checks, this is useful to check if the nodes has finished booting up and kubelet is running. Default is false.\",\n\t\t\t},\n\t\t\t\"client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The client configuration data\",\n\t\t\t},\n\t\t\t\"timeouts\": timeouts.Attributes(ctx, timeouts.Opts{\n\t\t\t\tRead: true,\n\t\t\t}),\n\t\t},\n\t}\n}\n\nfunc (d *talosClusterHealthDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {\n\tvar state talosClusterHealthDataSourceModelV0\n\n\tdiags := req.Config.Get(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar (\n\t\tendpoints         []string\n\t\tcontrolPlaneNodes []string\n\t\tworkerNodes       []string\n\t)\n\n\tresp.Diagnostics.Append(state.Endpoints.ElementsAs(ctx, &endpoints, true)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tresp.Diagnostics.Append(state.ControlPlaneNodes.ElementsAs(ctx, &controlPlaneNodes, true)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tresp.Diagnostics.Append(state.WorkerNodes.ElementsAs(ctx, &workerNodes, true)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\treadTimeout, diags := state.Timeouts.Read(ctx, 10*time.Minute)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\ttalosConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\t\"dynamic\",\n\t\tstate.ClientConfiguration.CA.ValueString(),\n\t\tstate.ClientConfiguration.Cert.ValueString(),\n\t\tstate.ClientConfiguration.Key.ValueString(),\n\t)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to generate talos config\", err.Error())\n\n\t\treturn\n\t}\n\n\tc, err := client.New(ctx, client.WithConfig(talosConfig), client.WithEndpoints(endpoints...))\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to create talos client\", err.Error())\n\n\t\treturn\n\t}\n\n\tdefer c.Close() //nolint:errcheck\n\n\tclientProvider := &cluster.ConfigClientProvider{\n\t\tDefaultClient: c,\n\t}\n\tdefer clientProvider.Close() //nolint:errcheck\n\n\tnodeInfos, err := newClusterNodes(controlPlaneNodes, workerNodes)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to generate node infos\", err.Error())\n\n\t\treturn\n\t}\n\n\tclusterState := struct {\n\t\tcluster.ClientProvider\n\t\tcluster.K8sProvider\n\t\tcluster.Info\n\t}{\n\t\tClientProvider: clientProvider,\n\t\tK8sProvider: &cluster.KubernetesClient{\n\t\t\tClientProvider: clientProvider,\n\t\t},\n\t\tInfo: nodeInfos,\n\t}\n\n\t// Run cluster readiness checks\n\tcheckCtx, checkCtxCancel := context.WithTimeout(ctx, readTimeout)\n\tdefer checkCtxCancel()\n\n\treporter := newReporter()\n\n\tchecks := check.PreBootSequenceChecks()\n\n\tif !state.SkipKubernetesChecks.ValueBool() {\n\t\tchecks = check.DefaultClusterChecks()\n\t}\n\n\tif err := check.Wait(checkCtx, &clusterState, checks, reporter); err != nil {\n\t\tresp.Diagnostics.AddWarning(\"failed checks\", reporter.String())\n\t\tresp.Diagnostics.AddError(\"cluster health check failed\", err.Error())\n\n\t\treturn\n\t}\n\n\tstate.ID = basetypes.NewStringValue(\"cluster_health\")\n\n\tresp.Diagnostics.Append(resp.State.Set(ctx, &state)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_cluster_health_data_source_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/acctest\"\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n)\n\nfunc TestAccTalosClusterHealthDataSource(t *testing.T) {\n\trName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)\n\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\"libvirt\": {\n\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t},\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: testAccTalosClusterHealthDataSourceConfig(\"talos\", rName),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_cluster_health.this\", \"id\", \"cluster_health\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// make sure there are no changes\n\t\t\t{\n\t\t\t\tConfig:   testAccTalosClusterHealthDataSourceConfig(\"talos\", rName),\n\t\t\t\tPlanOnly: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosClusterHealthDataSourceConfig(providerName, rName string) string {\n\tconfig := dynamicConfig{\n\t\tProvider:               providerName,\n\t\tResourceName:           rName,\n\t\tWithApplyConfig:        true,\n\t\tWithBootstrap:          true,\n\t\tWithRetrieveKubeConfig: true,\n\t\tWithClusterHealth:      true,\n\t}\n\n\treturn config.render()\n}\n"
  },
  {
    "path": "pkg/talos/talos_cluster_health_ephemeral_resource.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework/ephemeral\"\n\t\"github.com/hashicorp/terraform-plugin-framework/ephemeral/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/siderolabs/talos/pkg/cluster\"\n\t\"github.com/siderolabs/talos/pkg/cluster/check\"\n\t\"github.com/siderolabs/talos/pkg/conditions\"\n\t\"github.com/siderolabs/talos/pkg/machinery/client\"\n)\n\nvar _ ephemeral.EphemeralResource = &talosClusterHealthEphemeralResource{}\n\ntype talosClusterHealthEphemeralResource struct{}\n\ntype talosClusterHealthEphemeralResourceModel struct {\n\tClientConfiguration  clientConfiguration `tfsdk:\"client_configuration\"`\n\tEndpoints            types.List          `tfsdk:\"endpoints\"`\n\tControlPlaneNodes    types.List          `tfsdk:\"control_plane_nodes\"`\n\tWorkerNodes          types.List          `tfsdk:\"worker_nodes\"`\n\tTimeout              types.String        `tfsdk:\"timeout\"`\n\tSkipKubernetesChecks types.Bool          `tfsdk:\"skip_kubernetes_checks\"`\n}\n\ntype healthReporter struct {\n\tlastLine string\n\ts        strings.Builder\n}\n\nfunc newHealthReporter() *healthReporter {\n\treturn &healthReporter{}\n}\n\n// Update implements the conditions.Reporter interface.\nfunc (r *healthReporter) Update(condition conditions.Condition) {\n\tif condition.String() != r.lastLine {\n\t\tfmt.Fprintf(&r.s, \"waiting for %s\\n\", condition.String())\n\t\tr.lastLine = condition.String()\n\t}\n}\n\n// String returns the string representation of the reporter.\nfunc (r *healthReporter) String() string {\n\treturn r.s.String()\n}\n\n// NewTalosClusterHealthEphemeralResource implements the ephemeral.EphemeralResource interface.\nfunc NewTalosClusterHealthEphemeralResource() ephemeral.EphemeralResource {\n\treturn &talosClusterHealthEphemeralResource{}\n}\n\nfunc (r *talosClusterHealthEphemeralResource) Metadata(_ context.Context, req ephemeral.MetadataRequest, resp *ephemeral.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_cluster_health\"\n}\n\nfunc (r *talosClusterHealthEphemeralResource) Schema(_ context.Context, _ ephemeral.SchemaRequest, resp *ephemeral.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"Checks the health of a Talos cluster. This is an ephemeral resource that does not persist secrets in Terraform state.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"endpoints\": schema.ListAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tElementType: types.StringType,\n\t\t\t\tDescription: \"endpoints to use for the health check client. Use at least one control plane endpoint.\",\n\t\t\t},\n\t\t\t\"control_plane_nodes\": schema.ListAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tElementType: types.StringType,\n\t\t\t\tDescription: \"List of control plane nodes to check for health.\",\n\t\t\t},\n\t\t\t\"worker_nodes\": schema.ListAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tElementType: types.StringType,\n\t\t\t\tDescription: \"List of worker nodes to check for health.\",\n\t\t\t},\n\t\t\t\"skip_kubernetes_checks\": schema.BoolAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"Skip Kubernetes component checks, this is useful to check if the nodes has finished booting up and kubelet is running. Default is false.\",\n\t\t\t},\n\t\t\t\"client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The client configuration data\",\n\t\t\t},\n\t\t\t\"timeout\": schema.StringAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"Timeout for the health check. Defaults to 10m. Valid time units are 'ns', 'us' (or 'µs'), 'ms', 's', 'm', 'h'.\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (r *talosClusterHealthEphemeralResource) Open(ctx context.Context, req ephemeral.OpenRequest, resp *ephemeral.OpenResponse) {\n\tvar config talosClusterHealthEphemeralResourceModel\n\n\tdiags := req.Config.Get(ctx, &config)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar (\n\t\tendpoints         []string\n\t\tcontrolPlaneNodes []string\n\t\tworkerNodes       []string\n\t)\n\n\tresp.Diagnostics.Append(config.Endpoints.ElementsAs(ctx, &endpoints, true)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tresp.Diagnostics.Append(config.ControlPlaneNodes.ElementsAs(ctx, &controlPlaneNodes, true)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tresp.Diagnostics.Append(config.WorkerNodes.ElementsAs(ctx, &workerNodes, true)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\t// Parse timeout\n\ttimeout := 10 * time.Minute\n\n\tif !config.Timeout.IsNull() && !config.Timeout.IsUnknown() {\n\t\tvar err error\n\n\t\ttimeout, err = time.ParseDuration(config.Timeout.ValueString())\n\t\tif err != nil {\n\t\t\tresp.Diagnostics.AddError(\"Invalid timeout\", fmt.Sprintf(\"Unable to parse timeout: %s\", err.Error()))\n\n\t\t\treturn\n\t\t}\n\t}\n\n\ttalosConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\t\"dynamic\",\n\t\tconfig.ClientConfiguration.CA.ValueString(),\n\t\tconfig.ClientConfiguration.Cert.ValueString(),\n\t\tconfig.ClientConfiguration.Key.ValueString(),\n\t)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to generate talos config\", err.Error())\n\n\t\treturn\n\t}\n\n\tc, err := client.New(ctx, client.WithConfig(talosConfig), client.WithEndpoints(endpoints...))\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to create talos client\", err.Error())\n\n\t\treturn\n\t}\n\n\tdefer c.Close() //nolint:errcheck\n\n\tclientProvider := &cluster.ConfigClientProvider{\n\t\tDefaultClient: c,\n\t}\n\tdefer clientProvider.Close() //nolint:errcheck\n\n\tnodeInfos, err := newClusterNodes(controlPlaneNodes, workerNodes)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to generate node infos\", err.Error())\n\n\t\treturn\n\t}\n\n\tclusterState := struct {\n\t\tcluster.ClientProvider\n\t\tcluster.K8sProvider\n\t\tcluster.Info\n\t}{\n\t\tClientProvider: clientProvider,\n\t\tK8sProvider: &cluster.KubernetesClient{\n\t\t\tClientProvider: clientProvider,\n\t\t},\n\t\tInfo: nodeInfos,\n\t}\n\n\t// Run cluster readiness checks\n\tcheckCtx, checkCtxCancel := context.WithTimeout(ctx, timeout)\n\tdefer checkCtxCancel()\n\n\treporter := newHealthReporter()\n\n\tchecks := check.PreBootSequenceChecks()\n\n\tif !config.SkipKubernetesChecks.ValueBool() {\n\t\tchecks = check.DefaultClusterChecks()\n\t}\n\n\tif err := check.Wait(checkCtx, &clusterState, checks, reporter); err != nil {\n\t\tresp.Diagnostics.AddWarning(\"failed checks\", reporter.String())\n\t\tresp.Diagnostics.AddError(\"cluster health check failed\", err.Error())\n\n\t\treturn\n\t}\n\n\t// Set result - ephemeral resources can set a result or just complete successfully\n\tresp.Diagnostics.Append(resp.Result.Set(ctx, &config)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_cluster_kubeconfig_data_source.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry\"\n\t\"github.com/siderolabs/talos/pkg/machinery/client\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n\t\"k8s.io/client-go/tools/clientcmd\"\n)\n\ntype talosClusterKubeConfigDataSource struct{}\n\ntype talosClusterKubeConfigDataSourceModelV0 struct { //nolint:govet\n\tID                            types.String                  `tfsdk:\"id\"`\n\tNode                          types.String                  `tfsdk:\"node\"`\n\tEndpoint                      types.String                  `tfsdk:\"endpoint\"`\n\tClientConfiguration           clientConfiguration           `tfsdk:\"client_configuration\"`\n\tKubeConfigRaw                 types.String                  `tfsdk:\"kubeconfig_raw\"`\n\tKubernetesClientConfiguration kubernetesClientConfiguration `tfsdk:\"kubernetes_client_configuration\"`\n\tWait                          types.Bool                    `tfsdk:\"wait\"`\n\tTimeouts                      timeouts.Value                `tfsdk:\"timeouts\"`\n}\n\nvar _ datasource.DataSource = &talosClusterKubeConfigDataSource{}\n\n// NewTalosClusterKubeConfigDataSource implements the datasource.DataSource interface.\nfunc NewTalosClusterKubeConfigDataSource() datasource.DataSource {\n\treturn &talosClusterKubeConfigDataSource{}\n}\n\nfunc (d *talosClusterKubeConfigDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_cluster_kubeconfig\"\n}\n\nfunc (d *talosClusterKubeConfigDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDeprecationMessage: \"Use `talos_cluster_kubeconfig` resource instead. This data source will be removed in the next minor version of the provider.\",\n\t\tDescription:        \"Retrieves the kubeconfig for a Talos cluster\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tComputed: true,\n\t\t\t},\n\t\t\t\"node\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"controlplane node to retrieve the kubeconfig from\",\n\t\t\t},\n\t\t\t\"endpoint\": schema.StringAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"endpoint to use for the talosclient. If not set, the node value will be used\",\n\t\t\t},\n\t\t\t\"client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The client configuration data\",\n\t\t\t},\n\t\t\t\"wait\": schema.BoolAttribute{\n\t\t\t\tOptional:           true,\n\t\t\t\tDescription:        \"Wait for the kubernetes api to be available\",\n\t\t\t\tDeprecationMessage: \"This attribute is deprecated and no-op. Will be removed in a future version. Use talos_cluster_health instead.\",\n\t\t\t},\n\t\t\t\"kubeconfig_raw\": schema.StringAttribute{\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The raw kubeconfig\",\n\t\t\t\tSensitive:   true,\n\t\t\t},\n\t\t\t\"kubernetes_client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"host\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The kubernetes host\",\n\t\t\t\t\t},\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The kubernetes CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The kubernetes client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The kubernetes client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The kubernetes client configuration\",\n\t\t\t},\n\t\t\t\"timeouts\": timeouts.Attributes(ctx, timeouts.Opts{\n\t\t\t\tRead: true,\n\t\t\t}),\n\t\t},\n\t}\n}\n\n// Read implements the datasource.DataSource interface.\nfunc (d *talosClusterKubeConfigDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {\n\tvar obj types.Object\n\n\tdiags := req.Config.Get(ctx, &obj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar state talosClusterKubeConfigDataSourceModelV0\n\n\tdiags = obj.As(ctx, &state, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\ttalosConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\t\"dynamic\",\n\t\tstate.ClientConfiguration.CA.ValueString(),\n\t\tstate.ClientConfiguration.Cert.ValueString(),\n\t\tstate.ClientConfiguration.Key.ValueString(),\n\t)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to generate talos config\", err.Error())\n\n\t\treturn\n\t}\n\n\tif state.Endpoint.IsNull() {\n\t\tstate.Endpoint = state.Node\n\t}\n\n\treadTimeout, diags := state.Timeouts.Read(ctx, 10*time.Minute)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tctxDeadline, cancel := context.WithTimeout(ctx, readTimeout)\n\tdefer cancel()\n\n\tif retryErr := retry.RetryContext(ctxDeadline, readTimeout, func() *retry.RetryError {\n\t\tif clientOpErr := talosClientOp(ctx, state.Endpoint.ValueString(), state.Node.ValueString(), talosConfig, func(nodeCtx context.Context, c *client.Client) error {\n\t\t\tkubeConfigBytes, clientErr := c.Kubeconfig(nodeCtx)\n\t\t\tif clientErr != nil {\n\t\t\t\treturn clientErr\n\t\t\t}\n\n\t\t\tstate.KubeConfigRaw = basetypes.NewStringValue(string(kubeConfigBytes))\n\n\t\t\treturn nil\n\t\t}); clientOpErr != nil {\n\t\t\tif s := status.Code(clientOpErr); s == codes.InvalidArgument {\n\t\t\t\treturn retry.NonRetryableError(clientOpErr)\n\t\t\t}\n\n\t\t\treturn retry.RetryableError(clientOpErr)\n\t\t}\n\n\t\treturn nil\n\t}); retryErr != nil {\n\t\tresp.Diagnostics.AddError(\"failed to retrieve kubeconfig\", retryErr.Error())\n\n\t\treturn\n\t}\n\n\tkubeConfig, err := clientcmd.Load([]byte(state.KubeConfigRaw.ValueString()))\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to parse kubeconfig\", err.Error())\n\n\t\treturn\n\t}\n\n\tclusterName := kubeConfig.Contexts[kubeConfig.CurrentContext].Cluster\n\tauthName := kubeConfig.Contexts[kubeConfig.CurrentContext].AuthInfo\n\n\tstate.KubernetesClientConfiguration = kubernetesClientConfiguration{\n\t\tHost:              basetypes.NewStringValue(kubeConfig.Clusters[clusterName].Server),\n\t\tCACertificate:     basetypes.NewStringValue(bytesToBase64(kubeConfig.Clusters[clusterName].CertificateAuthorityData)),\n\t\tClientCertificate: basetypes.NewStringValue(bytesToBase64(kubeConfig.AuthInfos[authName].ClientCertificateData)),\n\t\tClientKey:         basetypes.NewStringValue(bytesToBase64(kubeConfig.AuthInfos[authName].ClientKeyData)),\n\t}\n\n\tstate.ID = basetypes.NewStringValue(clusterName)\n\n\tdiags = resp.State.Set(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_cluster_kubeconfig_ephemeral_resource.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/sha256\"\n\tstdlibx509 \"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/ephemeral\"\n\t\"github.com/hashicorp/terraform-plugin-framework/ephemeral/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/schema/validator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/generate/secrets\"\n\t\"golang.org/x/crypto/hkdf\"\n\t\"k8s.io/client-go/tools/clientcmd\"\n\tclientcmdapi \"k8s.io/client-go/tools/clientcmd/api\"\n)\n\nvar _ ephemeral.EphemeralResource = &talosClusterKubeConfigEphemeralResource{}\n\ntype talosClusterKubeConfigEphemeralResource struct{}\n\ntype talosClusterKubeConfigEphemeralResourceModel struct {\n\tMachineSecrets                machineSecrets                `tfsdk:\"machine_secrets\"`\n\tClusterName                   types.String                  `tfsdk:\"cluster_name\"`\n\tEndpoint                      types.String                  `tfsdk:\"endpoint\"`\n\tNotBefore                     types.String                  `tfsdk:\"not_before\"`\n\tCrtTTL                        types.String                  `tfsdk:\"crt_ttl\"`\n\tKubeConfigRaw                 types.String                  `tfsdk:\"kubeconfig_raw\"`\n\tKubernetesClientConfiguration kubernetesClientConfiguration `tfsdk:\"kubernetes_client_configuration\"`\n}\n\n// NewTalosClusterKubeConfigEphemeralResource implements the ephemeral.EphemeralResource interface.\nfunc NewTalosClusterKubeConfigEphemeralResource() ephemeral.EphemeralResource {\n\treturn &talosClusterKubeConfigEphemeralResource{}\n}\n\nfunc (r *talosClusterKubeConfigEphemeralResource) Metadata(_ context.Context, req ephemeral.MetadataRequest, resp *ephemeral.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_cluster_kubeconfig\"\n}\n\nfunc (r *talosClusterKubeConfigEphemeralResource) Schema(_ context.Context, _ ephemeral.SchemaRequest, resp *ephemeral.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"Generate a kubeconfig for a Talos cluster from machine secrets. \" +\n\t\t\t\"This is an ephemeral resource that does not persist secrets in Terraform state. \" +\n\t\t\t\"The admin client certificate is generated with pinned timestamps so kubeconfig_raw \" +\n\t\t\t\"is byte-identical on every open as long as machine_secrets and not_before are unchanged.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"machine_secrets\": machineSecretsSchemaAttribute(),\n\t\t\t\"cluster_name\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The name of the cluster; embedded in the kubeconfig context and cluster names\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tstringvalidator.LengthAtLeast(1),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"endpoint\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The Kubernetes API server URL to embed in the kubeconfig (e.g. https://1.2.3.4:6443)\",\n\t\t\t},\n\t\t\t\"not_before\": schema.StringAttribute{\n\t\t\t\tOptional: true,\n\t\t\t\tDescription: \"RFC3339 timestamp to use as the NotBefore field of the generated admin client certificate. \" +\n\t\t\t\t\t\"When set, the certificate validity starts at this time and ends at not_before + crt_ttl. \" +\n\t\t\t\t\t\"Persist this value in a terraform_data resource so it is stable across plans and the \" +\n\t\t\t\t\t\"generated kubeconfig_raw is byte-identical on every open. \" +\n\t\t\t\t\t\"When omitted, the certificate uses the K8s CA's own NotBefore/NotAfter timestamps.\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\trfc3339Valid(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"crt_ttl\": schema.StringAttribute{\n\t\t\t\tOptional: true,\n\t\t\t\tDescription: \"The lifetime of the generated admin client certificate as a Go duration string \" +\n\t\t\t\t\t\"(e.g. \\\"8760h\\\" for 1 year, \\\"87600h\\\" for 10 years). Defaults to \\\"87600h\\\" (10 years). \" +\n\t\t\t\t\t\"Only used when not_before is set; when not_before is omitted the cert uses the K8s CA's NotAfter directly.\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tgoDurationValid(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"kubeconfig_raw\": schema.StringAttribute{\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The raw kubeconfig\",\n\t\t\t\tSensitive:   true,\n\t\t\t},\n\t\t\t\"kubernetes_client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"host\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The kubernetes host\",\n\t\t\t\t\t},\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The kubernetes CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The kubernetes client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The kubernetes client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The kubernetes client configuration\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (r *talosClusterKubeConfigEphemeralResource) Open(ctx context.Context, req ephemeral.OpenRequest, resp *ephemeral.OpenResponse) {\n\tvar obj types.Object\n\n\tdiags := req.Config.Get(ctx, &obj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar config talosClusterKubeConfigEphemeralResourceModel\n\n\tdiags = obj.As(ctx, &config, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tsecretsBundle, err := machineSecretsToSecretsBundle(talosMachineSecretsResourceModelV1{\n\t\tMachineSecrets: config.MachineSecrets,\n\t})\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to convert machine secrets to secrets bundle\", err.Error())\n\n\t\treturn\n\t}\n\n\tnotBefore, notAfter, tsErr := resolveClientConfigTimestamps(config.NotBefore.ValueString(), config.CrtTTL.ValueString(), secretsBundle.Certs.K8s.Crt)\n\tif tsErr != nil {\n\t\tresp.Diagnostics.AddError(tsErr.summary, tsErr.detail)\n\n\t\treturn\n\t}\n\n\tkc, err := GenerateKubeconfig(secretsBundle, config.ClusterName.ValueString(), config.Endpoint.ValueString(), notBefore, notAfter)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to generate kubeconfig\", err.Error())\n\n\t\treturn\n\t}\n\n\tresult := talosClusterKubeConfigEphemeralResourceModel{\n\t\tMachineSecrets: config.MachineSecrets,\n\t\tClusterName:    config.ClusterName,\n\t\tEndpoint:       config.Endpoint,\n\t\tNotBefore:      config.NotBefore,\n\t\tCrtTTL:         config.CrtTTL,\n\t\tKubeConfigRaw:  basetypes.NewStringValue(kc.Raw),\n\t\tKubernetesClientConfiguration: kubernetesClientConfiguration{\n\t\t\tHost:              basetypes.NewStringValue(config.Endpoint.ValueString()),\n\t\t\tCACertificate:     basetypes.NewStringValue(bytesToBase64(secretsBundle.Certs.K8s.Crt)),\n\t\t\tClientCertificate: basetypes.NewStringValue(bytesToBase64(kc.ClientCertPEM)),\n\t\t\tClientKey:         basetypes.NewStringValue(bytesToBase64(kc.ClientKeyPEM)),\n\t\t},\n\t}\n\n\tdiags = resp.Result.Set(ctx, &result)\n\tresp.Diagnostics.Append(diags...)\n}\n\n// KubeconfigResult holds the generated kubeconfig and its components.\ntype KubeconfigResult struct {\n\tRaw           string // Full kubeconfig YAML\n\tClientCertPEM []byte // PEM-encoded admin client certificate\n\tClientKeyPEM  []byte // PEM-encoded admin client private key\n}\n\n// GenerateKubeconfig generates a kubeconfig from the provided secrets bundle.\n//\n// The admin client certificate and key are derived deterministically using HKDF\n// (RFC 5869) seeded from the K8s CA private key and all cert-relevant inputs.\n// Same inputs always produce byte-identical output — no crypto/rand is used.\nfunc GenerateKubeconfig(bundle *secrets.Bundle, clusterName, endpoint string, notBefore, notAfter time.Time) (*KubeconfigResult, error) {\n\t// Parse CA certificate and private key from PEM.\n\tcaCertBlock, _ := pem.Decode(bundle.Certs.K8s.Crt)\n\tif caCertBlock == nil {\n\t\treturn nil, fmt.Errorf(\"error decoding K8s CA certificate PEM\")\n\t}\n\n\tcaCert, err := stdlibx509.ParseCertificate(caCertBlock.Bytes)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing K8s CA certificate: %w\", err)\n\t}\n\n\tcaKeyBlock, _ := pem.Decode(bundle.Certs.K8s.Key)\n\tif caKeyBlock == nil {\n\t\treturn nil, fmt.Errorf(\"error decoding K8s CA private key PEM\")\n\t}\n\n\tcaKey, err := stdlibx509.ParseECPrivateKey(caKeyBlock.Bytes)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing K8s CA private key: %w\", err)\n\t}\n\n\t// Build a deterministic byte stream via HKDF (RFC 5869). The secret is the\n\t// CA private key (stable in machine_secrets); the info string binds all\n\t// inputs that affect the cert so different parameters produce different keys.\n\tinfo := fmt.Sprintf(\"talos-kubeconfig:v1:%s:%s:%d:%d\", clusterName, endpoint, notBefore.Unix(), notAfter.Unix())\n\tdeterministicReader := hkdf.New(sha256.New, bundle.Certs.K8s.Key, []byte(\"talos-kubeconfig-v1\"), []byte(info))\n\n\t// Derive admin client ECDSA private key deterministically from HKDF output.\n\t// ecdsa.ParseRawPrivateKey constructs a key from raw bytes without using\n\t// crypto/rand (unlike ecdsa.GenerateKey which ignores the reader in Go 1.26+).\n\tadminKeyBytes := make([]byte, 32) // P-256 key size\n\tif _, err = deterministicReader.Read(adminKeyBytes); err != nil {\n\t\treturn nil, fmt.Errorf(\"error deriving admin key bytes: %w\", err)\n\t}\n\n\tadminKey, err := ecdsa.ParseRawPrivateKey(elliptic.P256(), adminKeyBytes)\n\tif err != nil {\n\t\t// The HKDF output might produce an invalid scalar (0 or >= n).\n\t\t// In practice this is astronomically unlikely for P-256 but handle it.\n\t\treturn nil, fmt.Errorf(\"error parsing derived admin key: %w\", err)\n\t}\n\n\t// Deterministic serial number from the same HKDF stream.\n\tserialBytes := make([]byte, 16)\n\tif _, err = deterministicReader.Read(serialBytes); err != nil {\n\t\treturn nil, fmt.Errorf(\"error deriving serial number: %w\", err)\n\t}\n\n\tserialNumber := new(big.Int).SetBytes(serialBytes)\n\n\t// Build and sign the admin client certificate.\n\ttemplate := &stdlibx509.Certificate{\n\t\tSerialNumber: serialNumber,\n\t\tSubject: pkix.Name{\n\t\t\tCommonName:   \"admin\",\n\t\t\tOrganization: []string{\"system:masters\"},\n\t\t},\n\t\tNotBefore: notBefore,\n\t\tNotAfter:  notAfter,\n\t\tKeyUsage:  stdlibx509.KeyUsageDigitalSignature | stdlibx509.KeyUsageKeyEncipherment,\n\t\tExtKeyUsage: []stdlibx509.ExtKeyUsage{\n\t\t\tstdlibx509.ExtKeyUsageClientAuth,\n\t\t},\n\t}\n\n\t// Use RFC 6979 deterministic signer for the CA signature. Go 1.26+ ignores\n\t// the io.Reader in ecdsa.Sign and always uses system randomness, so we must\n\t// implement deterministic ECDSA ourselves via a custom crypto.Signer.\n\tcaSigner := &deterministicECDSASigner{key: caKey}\n\n\t// The rand reader is unused: serial number is set explicitly and signing\n\t// goes through our deterministic crypto.Signer.\n\tcertDER, err := stdlibx509.CreateCertificate(nil, template, caCert, &adminKey.PublicKey, caSigner)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error signing admin certificate: %w\", err)\n\t}\n\n\t// PEM-encode the client cert and key.\n\tclientCertPEM := pem.EncodeToMemory(&pem.Block{Type: \"CERTIFICATE\", Bytes: certDER})\n\n\tadminKeyDER, err := stdlibx509.MarshalECPrivateKey(adminKey)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error marshaling admin private key: %w\", err)\n\t}\n\n\tclientKeyPEM := pem.EncodeToMemory(&pem.Block{Type: \"EC PRIVATE KEY\", Bytes: adminKeyDER})\n\n\t// Assemble kubeconfig.\n\tcfg := clientcmdapi.Config{\n\t\tAPIVersion: \"v1\",\n\t\tKind:       \"Config\",\n\t\tClusters: map[string]*clientcmdapi.Cluster{\n\t\t\tclusterName: {\n\t\t\t\tServer:                   endpoint,\n\t\t\t\tCertificateAuthorityData: bundle.Certs.K8s.Crt,\n\t\t\t},\n\t\t},\n\t\tAuthInfos: map[string]*clientcmdapi.AuthInfo{\n\t\t\t\"admin@\" + clusterName: {\n\t\t\t\tClientCertificateData: clientCertPEM,\n\t\t\t\tClientKeyData:         clientKeyPEM,\n\t\t\t},\n\t\t},\n\t\tContexts: map[string]*clientcmdapi.Context{\n\t\t\t\"admin@\" + clusterName: {\n\t\t\t\tCluster:   clusterName,\n\t\t\t\tNamespace: \"default\",\n\t\t\t\tAuthInfo:  \"admin@\" + clusterName,\n\t\t\t},\n\t\t},\n\t\tCurrentContext: \"admin@\" + clusterName,\n\t}\n\n\tmarshaled, err := clientcmd.Write(cfg)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error marshaling kubeconfig: %w\", err)\n\t}\n\n\treturn &KubeconfigResult{\n\t\tRaw:           string(marshaled),\n\t\tClientCertPEM: clientCertPEM,\n\t\tClientKeyPEM:  clientKeyPEM,\n\t}, nil\n}\n"
  },
  {
    "path": "pkg/talos/talos_cluster_kubeconfig_ephemeral_resource_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"regexp\"\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n\t\"github.com/hashicorp/terraform-plugin-testing/knownvalue\"\n\t\"github.com/hashicorp/terraform-plugin-testing/plancheck\"\n\t\"github.com/hashicorp/terraform-plugin-testing/statecheck\"\n\t\"github.com/hashicorp/terraform-plugin-testing/tfjsonpath\"\n\t\"github.com/hashicorp/terraform-plugin-testing/tfversion\"\n)\n\n// TestAccTalosClusterKubeconfigEphemeralResourceBasic tests that the ephemeral resource\n// generates kubeconfig_raw and that kubernetes_client_configuration.host matches the endpoint.\nfunc TestAccTalosClusterKubeconfigEphemeralResourceBasic(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n\tendpoint        = \"https://10.0.0.1:6443\"\n}\n\nprovider \"echo\" {\n\tdata = {\n\t\tkubeconfig_raw = ephemeral.talos_cluster_kubeconfig.this.kubeconfig_raw\n\t\thost           = ephemeral.talos_cluster_kubeconfig.this.kubernetes_client_configuration.host\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"kubeconfig_raw\"), knownvalue.NotNull()),\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"host\"), knownvalue.StringExact(\"https://10.0.0.1:6443\")),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosClusterKubeconfigEphemeralResourceKubernetesClientConfigurationFields tests\n// that all kubernetes_client_configuration fields are populated.\nfunc TestAccTalosClusterKubeconfigEphemeralResourceKubernetesClientConfigurationFields(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n\tendpoint        = \"https://10.0.0.1:6443\"\n}\n\nprovider \"echo\" {\n\tdata = {\n\t\thost               = ephemeral.talos_cluster_kubeconfig.this.kubernetes_client_configuration.host\n\t\tca_certificate     = ephemeral.talos_cluster_kubeconfig.this.kubernetes_client_configuration.ca_certificate\n\t\tclient_certificate = ephemeral.talos_cluster_kubeconfig.this.kubernetes_client_configuration.client_certificate\n\t\tclient_key         = ephemeral.talos_cluster_kubeconfig.this.kubernetes_client_configuration.client_key\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"host\"), knownvalue.NotNull()),\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"ca_certificate\"), knownvalue.NotNull()),\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"client_certificate\"), knownvalue.NotNull()),\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"client_key\"), knownvalue.NotNull()),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosClusterKubeconfigEphemeralResourceDeterminism tests that two opens with\n// identical inputs (CA-pinned, no not_before) produce byte-identical kubeconfig_raw.\nfunc TestAccTalosClusterKubeconfigEphemeralResourceDeterminism(t *testing.T) {\n\tt.Parallel()\n\n\tcfg := `\nresource \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = talos_machine_secrets.this.machine_secrets\n\tendpoint        = \"https://10.0.0.1:6443\"\n}\n\nprovider \"echo\" {\n\tdata = {\n\t\tkubeconfig_raw = ephemeral.talos_cluster_kubeconfig.this.kubeconfig_raw\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: cfg,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"kubeconfig_raw\"), knownvalue.NotNull()),\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tConfig: cfg,\n\t\t\t\tConfigPlanChecks: resource.ConfigPlanChecks{\n\t\t\t\t\tPreApply: []plancheck.PlanCheck{\n\t\t\t\t\t\tplancheck.ExpectEmptyPlan(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosClusterKubeconfigEphemeralResourceDeterminismWithNotBefore tests that two\n// opens with a terraform_data-sourced not_before produce byte-identical kubeconfig_raw.\nfunc TestAccTalosClusterKubeconfigEphemeralResourceDeterminismWithNotBefore(t *testing.T) {\n\tt.Parallel()\n\n\tcfg := `\nresource \"talos_machine_secrets\" \"this\" {}\n\nresource \"terraform_data\" \"kubeconfig_nbf\" {\n\tinput = \"2024-01-01T00:00:00Z\"\n}\n\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = talos_machine_secrets.this.machine_secrets\n\tendpoint        = \"https://10.0.0.1:6443\"\n\tnot_before      = terraform_data.kubeconfig_nbf.output\n\tcrt_ttl         = \"87600h\"\n}\n\nprovider \"echo\" {\n\tdata = {\n\t\tkubeconfig_raw = ephemeral.talos_cluster_kubeconfig.this.kubeconfig_raw\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: cfg,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"kubeconfig_raw\"), knownvalue.NotNull()),\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tConfig: cfg,\n\t\t\t\tConfigPlanChecks: resource.ConfigPlanChecks{\n\t\t\t\t\tPreApply: []plancheck.PlanCheck{\n\t\t\t\t\t\tplancheck.ExpectEmptyPlan(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosClusterKubeconfigEphemeralResourceCustomTTL tests that not_before + crt_ttl\n// are accepted and the resource opens without error.\nfunc TestAccTalosClusterKubeconfigEphemeralResourceCustomTTL(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n\tendpoint        = \"https://10.0.0.1:6443\"\n\tnot_before      = \"2024-01-01T00:00:00Z\"\n\tcrt_ttl         = \"8760h\"\n}\n\nprovider \"echo\" {\n\tdata = {\n\t\tkubeconfig_raw = ephemeral.talos_cluster_kubeconfig.this.kubeconfig_raw\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"kubeconfig_raw\"), knownvalue.NotNull()),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosClusterKubeconfigEphemeralResourceInvalidTTL tests that an invalid crt_ttl\n// is rejected with an error.\nfunc TestAccTalosClusterKubeconfigEphemeralResourceInvalidTTL(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n\tendpoint        = \"https://10.0.0.1:6443\"\n\tnot_before      = \"2024-01-01T00:00:00Z\"\n\tcrt_ttl         = \"not-a-duration\"\n}\n\nprovider \"echo\" {\n\tdata = {}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tExpectError: regexp.MustCompile(`invalid crt_ttl`),\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosClusterKubeconfigEphemeralResourceInvalidNotBefore tests that an invalid\n// not_before is rejected with an error.\nfunc TestAccTalosClusterKubeconfigEphemeralResourceInvalidNotBefore(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n\tcluster_name    = \"test-cluster\"\n\tmachine_secrets = ephemeral.talos_machine_secrets.this.machine_secrets\n\tendpoint        = \"https://10.0.0.1:6443\"\n\tnot_before      = \"not-a-timestamp\"\n}\n\nprovider \"echo\" {\n\tdata = {}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tExpectError: regexp.MustCompile(`invalid not_before`),\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "pkg/talos/talos_cluster_kubeconfig_resource.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts\"\n\t\"github.com/hashicorp/terraform-plugin-framework/path\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema/objectplanmodifier\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/hashicorp/terraform-plugin-log/tflog\"\n\t\"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry\"\n\t\"github.com/siderolabs/talos/pkg/machinery/client\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n\t\"k8s.io/client-go/tools/clientcmd\"\n)\n\ntype talosClusterKubeConfigResource struct{}\n\nvar (\n\t_ resource.Resource                 = &talosClusterKubeConfigResource{}\n\t_ resource.ResourceWithModifyPlan   = &talosClusterKubeConfigResource{}\n\t_ resource.ResourceWithUpgradeState = &talosClusterKubeConfigResource{}\n)\n\ntype talosClusterKubeConfigResourceModelV0 struct {\n\tID                            types.String                  `tfsdk:\"id\"`\n\tNode                          types.String                  `tfsdk:\"node\"`\n\tEndpoint                      types.String                  `tfsdk:\"endpoint\"`\n\tClientConfiguration           clientConfiguration           `tfsdk:\"client_configuration\"`\n\tKubeConfigRaw                 types.String                  `tfsdk:\"kubeconfig_raw\"`\n\tKubernetesClientConfiguration kubernetesClientConfiguration `tfsdk:\"kubernetes_client_configuration\"`\n\tTimeouts                      timeouts.Value                `tfsdk:\"timeouts\"`\n}\n\ntype talosClusterKubeConfigResourceModelV1 struct {\n\tID                            types.String                  `tfsdk:\"id\"`\n\tNode                          types.String                  `tfsdk:\"node\"`\n\tEndpoint                      types.String                  `tfsdk:\"endpoint\"`\n\tClientConfiguration           clientConfiguration           `tfsdk:\"client_configuration\"`\n\tKubeConfigRaw                 types.String                  `tfsdk:\"kubeconfig_raw\"`\n\tKubernetesClientConfiguration kubernetesClientConfiguration `tfsdk:\"kubernetes_client_configuration\"`\n\tCertificateRenewalDuration    types.String                  `tfsdk:\"certificate_renewal_duration\"`\n\tTimeouts                      timeouts.Value                `tfsdk:\"timeouts\"`\n}\n\ntype kubernetesClientConfiguration struct {\n\tHost              types.String `tfsdk:\"host\"`\n\tCACertificate     types.String `tfsdk:\"ca_certificate\"`\n\tClientCertificate types.String `tfsdk:\"client_certificate\"`\n\tClientKey         types.String `tfsdk:\"client_key\"`\n}\n\n// NewTalosClusterKubeConfigResource implements the resource.Resource interface.\nfunc NewTalosClusterKubeConfigResource() resource.Resource {\n\treturn &talosClusterKubeConfigResource{}\n}\n\nfunc (r *talosClusterKubeConfigResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_cluster_kubeconfig\"\n}\n\nfunc (r *talosClusterKubeConfigResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tVersion:     1,\n\t\tDescription: \"Retrieves the kubeconfig for a Talos cluster\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tComputed: true,\n\t\t\t\tPlanModifiers: []planmodifier.String{\n\t\t\t\t\tstringplanmodifier.UseStateForUnknown(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"node\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"controlplane node to retrieve the kubeconfig from\",\n\t\t\t},\n\t\t\t\"endpoint\": schema.StringAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"endpoint to use for the talosclient. If not set, the node value will be used\",\n\t\t\t},\n\t\t\t\"client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The client configuration data\",\n\t\t\t},\n\t\t\t\"kubeconfig_raw\": schema.StringAttribute{\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The raw kubeconfig\",\n\t\t\t\tSensitive:   true,\n\t\t\t\tPlanModifiers: []planmodifier.String{\n\t\t\t\t\tstringplanmodifier.UseStateForUnknown(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"kubernetes_client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"host\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The kubernetes host\",\n\t\t\t\t\t},\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The kubernetes CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The kubernetes client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The kubernetes client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The kubernetes client configuration\",\n\t\t\t\tPlanModifiers: []planmodifier.Object{\n\t\t\t\t\tobjectplanmodifier.UseStateForUnknown(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"certificate_renewal_duration\": schema.StringAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The duration in hours before the certificate is renewed, defaults to 720h. Must be a valid duration string\",\n\t\t\t\tDefault:     stringdefault.StaticString(\"720h\"),\n\t\t\t},\n\t\t\t\"timeouts\": timeouts.Attributes(ctx, timeouts.Opts{\n\t\t\t\tCreate: true,\n\t\t\t\tUpdate: true,\n\t\t\t}),\n\t\t},\n\t}\n}\n\n// Create implements the resource.Resource interface.\nfunc (r *talosClusterKubeConfigResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {\n\tvar obj types.Object\n\n\tdiags := req.Config.Get(ctx, &obj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar state talosClusterKubeConfigResourceModelV1\n\n\tdiags = obj.As(ctx, &state, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\ttalosConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\t\"dynamic\",\n\t\tstate.ClientConfiguration.CA.ValueString(),\n\t\tstate.ClientConfiguration.Cert.ValueString(),\n\t\tstate.ClientConfiguration.Key.ValueString(),\n\t)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to generate talos config\", err.Error())\n\n\t\treturn\n\t}\n\n\tif state.Endpoint.IsNull() {\n\t\tstate.Endpoint = state.Node\n\t}\n\n\treadTimeout, diags := state.Timeouts.Create(ctx, 10*time.Minute)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tctxDeadline, cancel := context.WithTimeout(ctx, readTimeout)\n\tdefer cancel()\n\n\tif retryErr := retry.RetryContext(ctxDeadline, readTimeout, func() *retry.RetryError {\n\t\tif clientOpErr := talosClientOp(ctx, state.Endpoint.ValueString(), state.Node.ValueString(), talosConfig, func(nodeCtx context.Context, c *client.Client) error {\n\t\t\tkubeConfigBytes, clientErr := c.Kubeconfig(nodeCtx)\n\t\t\tif clientErr != nil {\n\t\t\t\treturn clientErr\n\t\t\t}\n\n\t\t\tstate.KubeConfigRaw = basetypes.NewStringValue(string(kubeConfigBytes))\n\n\t\t\treturn nil\n\t\t}); clientOpErr != nil {\n\t\t\tif s := status.Code(clientOpErr); s == codes.InvalidArgument {\n\t\t\t\treturn retry.NonRetryableError(clientOpErr)\n\t\t\t}\n\n\t\t\treturn retry.RetryableError(clientOpErr)\n\t\t}\n\n\t\treturn nil\n\t}); retryErr != nil {\n\t\tresp.Diagnostics.AddError(\"failed to retrieve kubeconfig\", retryErr.Error())\n\n\t\treturn\n\t}\n\n\tkubeConfig, err := clientcmd.Load([]byte(state.KubeConfigRaw.ValueString()))\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to parse kubeconfig\", err.Error())\n\n\t\treturn\n\t}\n\n\tclusterName := kubeConfig.Contexts[kubeConfig.CurrentContext].Cluster\n\tauthName := kubeConfig.Contexts[kubeConfig.CurrentContext].AuthInfo\n\n\tstate.KubernetesClientConfiguration = kubernetesClientConfiguration{\n\t\tHost:              basetypes.NewStringValue(kubeConfig.Clusters[clusterName].Server),\n\t\tCACertificate:     basetypes.NewStringValue(bytesToBase64(kubeConfig.Clusters[clusterName].CertificateAuthorityData)),\n\t\tClientCertificate: basetypes.NewStringValue(bytesToBase64(kubeConfig.AuthInfos[authName].ClientCertificateData)),\n\t\tClientKey:         basetypes.NewStringValue(bytesToBase64(kubeConfig.AuthInfos[authName].ClientKeyData)),\n\t}\n\n\tstate.ID = basetypes.NewStringValue(clusterName)\n\n\tvar planObj types.Object\n\n\tdiags = req.Plan.Get(ctx, &planObj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar planState talosClusterKubeConfigResourceModelV1\n\n\tdiags = planObj.As(ctx, &planState, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif state.CertificateRenewalDuration.IsNull() || state.CertificateRenewalDuration.IsUnknown() {\n\t\tstate.CertificateRenewalDuration = planState.CertificateRenewalDuration\n\t}\n\n\tdiags = resp.State.Set(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n\nfunc (r *talosClusterKubeConfigResource) Delete(_ context.Context, _ resource.DeleteRequest, _ *resource.DeleteResponse) {\n}\n\nfunc (r *talosClusterKubeConfigResource) Read(_ context.Context, _ resource.ReadRequest, _ *resource.ReadResponse) {\n}\n\n// ModifyPlan implements the resource.ResourceWithModifyPlan interface.\n//\n//nolint:gocyclo,cyclop\nfunc (r *talosClusterKubeConfigResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {\n\t// delete is a no-op\n\tif req.Plan.Raw.IsNull() {\n\t\treturn\n\t}\n\n\tvar configObj types.Object\n\n\tdiags := req.Config.Get(ctx, &configObj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar config talosClusterKubeConfigResourceModelV1\n\n\tdiags = configObj.As(ctx, &config, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\t// if either endpoint or node is unknown return early\n\tif config.Endpoint.IsUnknown() || config.Node.IsUnknown() {\n\t\treturn\n\t}\n\n\tvar planObj types.Object\n\n\tdiags = req.Plan.Get(ctx, &planObj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar planState talosClusterKubeConfigResourceModelV1\n\n\tdiags = configObj.As(ctx, &planState, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif planState.Endpoint.IsUnknown() || planState.Endpoint.IsNull() {\n\t\tdiags = resp.Plan.SetAttribute(ctx, path.Root(\"endpoint\"), planState.Node.ValueString())\n\t\tresp.Diagnostics.Append(diags...)\n\n\t\tif diags.HasError() {\n\t\t\treturn\n\t\t}\n\t}\n\n\tkubernetesClientConfigPath := path.Root(\"kubernetes_client_configuration\")\n\n\tvar obj types.Object\n\n\tresp.Diagnostics.Append(req.State.GetAttribute(ctx, kubernetesClientConfigPath, &obj)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar kubernetesClientConfig kubernetesClientConfiguration\n\n\tresp.Diagnostics.Append(obj.As(ctx, &kubernetesClientConfig, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif kubernetesClientConfig.ClientCertificate.IsNull() || kubernetesClientConfig.ClientCertificate.IsUnknown() {\n\t\treturn\n\t}\n\n\tkubernetesClientCertificate := kubernetesClientConfig.ClientCertificate.ValueString()\n\n\tkubernetesClientCertificateBytes, err := base64ToBytes(kubernetesClientCertificate)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to decode kubernetes client certificate\", err.Error())\n\n\t\treturn\n\t}\n\n\tblock, _ := pem.Decode(kubernetesClientCertificateBytes)\n\tif block == nil {\n\t\tresp.Diagnostics.AddError(\"failed to decode kubernetes client certificate\", \"failed to decode PEM block\")\n\n\t\treturn\n\t}\n\n\tx509Cert, err := x509.ParseCertificate(block.Bytes)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to parse kubernetes client certificate\", err.Error())\n\n\t\treturn\n\t}\n\n\tvar exisitingStateObj types.Object\n\n\tdiags = req.State.Get(ctx, &exisitingStateObj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar existingState talosClusterKubeConfigResourceModelV1\n\n\tdiags = exisitingStateObj.As(ctx, &existingState, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif planState.CertificateRenewalDuration.IsNull() || planState.CertificateRenewalDuration.IsUnknown() {\n\t\tplanState.CertificateRenewalDuration = existingState.CertificateRenewalDuration\n\t}\n\n\trenewalDuration, err := time.ParseDuration(planState.CertificateRenewalDuration.ValueString())\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to parse certificate renewal duration in plan\", err.Error())\n\n\t\treturn\n\t}\n\n\t// check if NotAfter expires in the given duration\n\tif x509Cert.NotAfter.Before(OverridableTimeFunc().Add(renewalDuration)) {\n\t\ttflog.Info(ctx, fmt.Sprintf(\"kubernetes client certificate expires in %s, needs regeneration\", existingState.CertificateRenewalDuration.ValueString()))\n\n\t\tresp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, path.Root(\"kubernetes_client_configuration\").AtName(\"host\"), types.StringUnknown())...)\n\t\tresp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, path.Root(\"kubernetes_client_configuration\").AtName(\"client_certificate\"), types.StringUnknown())...)\n\t\tresp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, path.Root(\"kubernetes_client_configuration\").AtName(\"client_key\"), types.StringUnknown())...)\n\t\tresp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, path.Root(\"kubernetes_client_configuration\").AtName(\"ca_certificate\"), types.StringUnknown())...)\n\t\tresp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, path.Root(\"kubeconfig_raw\"), types.StringUnknown())...)\n\n\t\tif resp.Diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (r *talosClusterKubeConfigResource) UpgradeState(ctx context.Context) map[int64]resource.StateUpgrader {\n\treturn map[int64]resource.StateUpgrader{\n\t\t0: {\n\t\t\tPriorSchema: &schema.Schema{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\t\t\tComputed: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"node\": schema.StringAttribute{\n\t\t\t\t\t\tRequired: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"endpoint\": schema.StringAttribute{\n\t\t\t\t\t\tOptional: true,\n\t\t\t\t\t\tComputed: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\t\t\tRequired: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\t\t\tRequired: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\t\t\tRequired:  true,\n\t\t\t\t\t\t\t\tSensitive: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRequired: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"kubeconfig_raw\": schema.StringAttribute{\n\t\t\t\t\t\tComputed: true,\n\n\t\t\t\t\t\tSensitive: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"kubernetes_client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\t\t\"host\": schema.StringAttribute{\n\t\t\t\t\t\t\t\tComputed: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\t\t\tComputed: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\t\t\tComputed: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\t\t\tComputed:  true,\n\t\t\t\t\t\t\t\tSensitive: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tComputed: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"timeouts\": timeouts.Attributes(ctx, timeouts.Opts{\n\t\t\t\t\t\tCreate: true,\n\t\t\t\t\t\tUpdate: true,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t},\n\t\t\tStateUpgrader: func(ctx context.Context, req resource.UpgradeStateRequest, resp *resource.UpgradeStateResponse) {\n\t\t\t\tvar obj types.Object\n\n\t\t\t\tdiags := req.State.Get(ctx, &obj)\n\t\t\t\tresp.Diagnostics.Append(diags...)\n\n\t\t\t\tif diags.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tvar priorStateData talosClusterKubeConfigResourceModelV0\n\n\t\t\t\tdiags = obj.As(ctx, &priorStateData, basetypes.ObjectAsOptions{\n\t\t\t\t\tUnhandledNullAsEmpty:    true,\n\t\t\t\t\tUnhandledUnknownAsEmpty: true,\n\t\t\t\t})\n\t\t\t\tresp.Diagnostics.Append(diags...)\n\n\t\t\t\tif diags.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tstate := talosClusterKubeConfigResourceModelV1{\n\t\t\t\t\tID:                  priorStateData.ID,\n\t\t\t\t\tNode:                priorStateData.Node,\n\t\t\t\t\tEndpoint:            priorStateData.Endpoint,\n\t\t\t\t\tClientConfiguration: priorStateData.ClientConfiguration,\n\t\t\t\t\tKubeConfigRaw:       priorStateData.KubeConfigRaw,\n\t\t\t\t\tKubernetesClientConfiguration: kubernetesClientConfiguration{\n\t\t\t\t\t\tHost:              priorStateData.KubernetesClientConfiguration.Host,\n\t\t\t\t\t\tCACertificate:     priorStateData.KubernetesClientConfiguration.CACertificate,\n\t\t\t\t\t\tClientCertificate: priorStateData.KubernetesClientConfiguration.ClientCertificate,\n\t\t\t\t\t\tClientKey:         priorStateData.KubernetesClientConfiguration.ClientKey,\n\t\t\t\t\t},\n\t\t\t\t\tCertificateRenewalDuration: basetypes.NewStringValue(\"720h\"),\n\t\t\t\t\tTimeouts:                   priorStateData.Timeouts,\n\t\t\t\t}\n\n\t\t\t\t// Set state to fully populated data\n\t\t\t\tdiags = resp.State.Set(ctx, &state)\n\n\t\t\t\tresp.Diagnostics.Append(diags...)\n\n\t\t\t\tif resp.Diagnostics.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t}\n}\n\n// Update implements the resource.ResourceWithModifyPlan interface.\n//\n//nolint:gocognit,gocyclo,cyclop\nfunc (r *talosClusterKubeConfigResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {\n\tvar planObj types.Object\n\n\tresp.Diagnostics.Append(req.Plan.Get(ctx, &planObj)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar state talosClusterKubeConfigResourceModelV1\n\n\tresp.Diagnostics.Append(planObj.As(ctx, &state, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tresp.Diagnostics.Append(resp.State.Set(ctx, &state)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tkubernetesClientConfigPath := path.Root(\"kubernetes_client_configuration\")\n\n\tvar stateObj types.Object\n\n\tresp.Diagnostics.Append(req.State.GetAttribute(ctx, kubernetesClientConfigPath, &stateObj)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar kubernetesClientConfig kubernetesClientConfiguration\n\n\tresp.Diagnostics.Append(stateObj.As(ctx, &kubernetesClientConfig, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif kubernetesClientConfig.ClientCertificate.IsNull() || kubernetesClientConfig.ClientCertificate.IsUnknown() {\n\t\treturn\n\t}\n\n\tkubernetesClientCertificate := kubernetesClientConfig.ClientCertificate.ValueString()\n\n\tkubernetesClientCertificateBytes, err := base64ToBytes(kubernetesClientCertificate)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to decode kubernetes client certificate\", err.Error())\n\n\t\treturn\n\t}\n\n\tblock, _ := pem.Decode(kubernetesClientCertificateBytes)\n\tif block == nil {\n\t\tresp.Diagnostics.AddError(\"failed to decode kubernetes client certificate\", \"failed to decode PEM block\")\n\n\t\treturn\n\t}\n\n\tx509Cert, err := x509.ParseCertificate(block.Bytes)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to parse kubernetes client certificate\", err.Error())\n\n\t\treturn\n\t}\n\n\trenewalDuration, err := time.ParseDuration(state.CertificateRenewalDuration.ValueString())\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to parse certificate renewal duration\", err.Error())\n\n\t\treturn\n\t}\n\n\t// check if NotAfter expires in the given duration\n\tif x509Cert.NotAfter.Before(OverridableTimeFunc().Add(renewalDuration)) {\n\t\ttflog.Info(ctx, fmt.Sprintf(\"kubernetes client certificate expires in %s, regenerating\", state.CertificateRenewalDuration.ValueString()))\n\n\t\ttalosConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\t\t\"dynamic\",\n\t\t\tstate.ClientConfiguration.CA.ValueString(),\n\t\t\tstate.ClientConfiguration.Cert.ValueString(),\n\t\t\tstate.ClientConfiguration.Key.ValueString(),\n\t\t)\n\t\tif err != nil {\n\t\t\tresp.Diagnostics.AddError(\"failed to generate talos config\", err.Error())\n\n\t\t\treturn\n\t\t}\n\n\t\tif state.Endpoint.IsNull() {\n\t\t\tstate.Endpoint = state.Node\n\t\t}\n\n\t\tupdateTimeout, diags := state.Timeouts.Update(ctx, 10*time.Minute)\n\t\tresp.Diagnostics.Append(diags...)\n\n\t\tif resp.Diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\n\t\tctxDeadline, cancel := context.WithTimeout(ctx, updateTimeout)\n\t\tdefer cancel()\n\n\t\tif retryErr := retry.RetryContext(ctxDeadline, updateTimeout, func() *retry.RetryError {\n\t\t\tif clientOpErr := talosClientOp(ctx, state.Endpoint.ValueString(), state.Node.ValueString(), talosConfig, func(nodeCtx context.Context, c *client.Client) error {\n\t\t\t\tkubeConfigBytes, clientErr := c.Kubeconfig(nodeCtx)\n\t\t\t\tif clientErr != nil {\n\t\t\t\t\treturn clientErr\n\t\t\t\t}\n\n\t\t\t\tstate.KubeConfigRaw = basetypes.NewStringValue(string(kubeConfigBytes))\n\n\t\t\t\treturn nil\n\t\t\t}); clientOpErr != nil {\n\t\t\t\tif s := status.Code(clientOpErr); s == codes.InvalidArgument {\n\t\t\t\t\treturn retry.NonRetryableError(clientOpErr)\n\t\t\t\t}\n\n\t\t\t\treturn retry.RetryableError(clientOpErr)\n\t\t\t}\n\n\t\t\treturn nil\n\t\t}); retryErr != nil {\n\t\t\tresp.Diagnostics.AddError(\"failed to retrieve kubeconfig\", retryErr.Error())\n\n\t\t\treturn\n\t\t}\n\n\t\tkubeConfig, err := clientcmd.Load([]byte(state.KubeConfigRaw.ValueString()))\n\t\tif err != nil {\n\t\t\tresp.Diagnostics.AddError(\"failed to parse kubeconfig\", err.Error())\n\n\t\t\treturn\n\t\t}\n\n\t\tclusterName := kubeConfig.Contexts[kubeConfig.CurrentContext].Cluster\n\t\tauthName := kubeConfig.Contexts[kubeConfig.CurrentContext].AuthInfo\n\n\t\tstate.KubernetesClientConfiguration = kubernetesClientConfiguration{\n\t\t\tHost:              basetypes.NewStringValue(kubeConfig.Clusters[clusterName].Server),\n\t\t\tCACertificate:     basetypes.NewStringValue(bytesToBase64(kubeConfig.Clusters[clusterName].CertificateAuthorityData)),\n\t\t\tClientCertificate: basetypes.NewStringValue(bytesToBase64(kubeConfig.AuthInfos[authName].ClientCertificateData)),\n\t\t\tClientKey:         basetypes.NewStringValue(bytesToBase64(kubeConfig.AuthInfos[authName].ClientKeyData)),\n\t\t}\n\n\t\tresp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(\"kubernetes_client_configuration\").AtName(\"host\"), &state.KubernetesClientConfiguration.Host)...)\n\t\tresp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(\"kubernetes_client_configuration\").AtName(\"client_certificate\"), &state.KubernetesClientConfiguration.ClientCertificate)...)\n\t\tresp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(\"kubernetes_client_configuration\").AtName(\"client_key\"), &state.KubernetesClientConfiguration.ClientKey)...)\n\t\tresp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(\"kubernetes_client_configuration\").AtName(\"ca_certificate\"), &state.KubernetesClientConfiguration.CACertificate)...)\n\t\tresp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(\"kubeconfig_raw\"), &state.KubeConfigRaw)...)\n\n\t\tif resp.Diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_cluster_kubeconfig_resource_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/acctest\"\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n\n\t\"github.com/siderolabs/terraform-provider-talos/pkg/talos\"\n)\n\nfunc TestAccTalosClusterKubeconfigResource(t *testing.T) {\n\ttestTime := time.Now()\n\n\trName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)\n\n\tresource.Test(t, resource.TestCase{\n\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\"libvirt\": {\n\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t},\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: testAccTalosClusterKubeconfigResourceConfig(rName),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_cluster_kubeconfig.this\", \"id\", \"example-cluster\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"node\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"endpoint\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"client_configuration.client_key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"kubeconfig_raw\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"kubernetes_client_configuration.host\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"kubernetes_client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"kubernetes_client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"kubernetes_client_configuration.client_key\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// test kubeconfig regeneration\n\t\t\t{\n\t\t\t\tPreConfig: func() {\n\t\t\t\t\ttalos.OverridableTimeFunc = func() time.Time {\n\t\t\t\t\t\treturn testTime.AddDate(0, 12, 5)\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tConfig:             testAccTalosClusterKubeconfigResourceConfig(rName),\n\t\t\t\tPlanOnly:           true,\n\t\t\t\tExpectNonEmptyPlan: true,\n\t\t\t},\n\t\t},\n\t})\n\n\ttalos.OverridableTimeFunc = func() time.Time {\n\t\treturn testTime\n\t}\n\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\"libvirt\": {\n\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t},\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: testAccTalosClusterKubeconfigResourceConfig(rName),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_cluster_kubeconfig.this\", \"id\", \"example-cluster\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"node\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"endpoint\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"client_configuration.client_key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"kubeconfig_raw\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"kubernetes_client_configuration.host\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"kubernetes_client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"kubernetes_client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_cluster_kubeconfig.this\", \"kubernetes_client_configuration.client_key\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// make sure there are no changes\n\t\t\t{\n\t\t\t\tConfig:   testAccTalosClusterKubeconfigResourceConfig(rName),\n\t\t\t\tPlanOnly: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosClusterKubeconfigResourceConfig(rName string) string {\n\tconfig := dynamicConfig{\n\t\tProvider:               \"talos\",\n\t\tResourceName:           rName,\n\t\tWithApplyConfig:        true,\n\t\tWithBootstrap:          true,\n\t\tWithRetrieveKubeConfig: true,\n\t}\n\n\treturn config.render()\n}\n"
  },
  {
    "path": "pkg/talos/talos_image_factory_extensions_versions_data_source.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework/attr\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/path\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/siderolabs/gen/xslices\"\n\t\"github.com/siderolabs/image-factory/pkg/client\"\n)\n\ntype talosImageFactoryExtensionsVersionsDataSource struct {\n\timageFactoryClient *client.Client\n}\n\ntype talosImageFactoryExtensionsVersionsDataSourceModelV0 struct {\n\tID             types.String                               `tfsdk:\"id\"`\n\tTalosVersion   types.String                               `tfsdk:\"talos_version\"`\n\tFilters        *talosImageFactoryExtensionsVersionsFilter `tfsdk:\"filters\"`\n\tExactFilters   *talosImageFactoryExtensionsVersionsFilter `tfsdk:\"exact_filters\"`\n\tExtensionsInfo []extensionInfo                            `tfsdk:\"extensions_info\"`\n}\n\ntype talosImageFactoryExtensionsVersionsFilter struct {\n\tNames types.List `tfsdk:\"names\"`\n}\n\ntype extensionInfo struct {\n\tName        types.String `tfsdk:\"name\"`\n\tRef         types.String `tfsdk:\"ref\"`\n\tDigest      types.String `tfsdk:\"digest\"`\n\tAuthor      types.String `tfsdk:\"author\"`\n\tDescription types.String `tfsdk:\"description\"`\n}\n\nvar _ datasource.DataSourceWithConfigure = &talosImageFactoryExtensionsVersionsDataSource{}\n\n// NewTalosImageFactoryExtensionsVersionsDataSource implements the datasource.DataSource interface.\nfunc NewTalosImageFactoryExtensionsVersionsDataSource() datasource.DataSource {\n\treturn &talosImageFactoryExtensionsVersionsDataSource{}\n}\n\nfunc (d *talosImageFactoryExtensionsVersionsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_image_factory_extensions_versions\"\n}\n\nfunc (d *talosImageFactoryExtensionsVersionsDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"The image factory extensions versions data source provides a list of available extensions for a specific talos version from the image factory.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tComputed: true,\n\t\t\t},\n\t\t\t\"talos_version\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The talos version to get extensions for.\",\n\t\t\t},\n\t\t\t\"filters\": schema.SingleNestedAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"The filter to apply to the extensions list.\",\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"names\": schema.ListAttribute{\n\t\t\t\t\t\tElementType: types.StringType,\n\t\t\t\t\t\tOptional:    true,\n\t\t\t\t\t\tDescription: \"The name of the extension to filter by.\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"exact_filters\": schema.SingleNestedAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"The filter to apply to the extensions list.\",\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"names\": schema.ListAttribute{\n\t\t\t\t\t\tElementType: types.StringType,\n\t\t\t\t\t\tOptional:    true,\n\t\t\t\t\t\tDescription: \"The exact name match of the extension to filter by.\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"extensions_info\": schema.ListAttribute{\n\t\t\t\tElementType: types.ObjectType{\n\t\t\t\t\tAttrTypes: map[string]attr.Type{\n\t\t\t\t\t\t\"name\":        types.StringType,\n\t\t\t\t\t\t\"ref\":         types.StringType,\n\t\t\t\t\t\t\"digest\":      types.StringType,\n\t\t\t\t\t\t\"author\":      types.StringType,\n\t\t\t\t\t\t\"description\": types.StringType,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The list of available extensions for the specified talos version.\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (d *talosImageFactoryExtensionsVersionsDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {\n\tif req.ProviderData == nil {\n\t\treturn\n\t}\n\n\timageFactoryClient, ok := req.ProviderData.(*client.Client)\n\tif !ok {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to get image factory client\",\n\t\t\tfmt.Sprintf(\"Expected *client.Client, got: %T. Please report this issue to the provider developers.\", req.ProviderData),\n\t\t)\n\n\t\treturn\n\t}\n\n\td.imageFactoryClient = imageFactoryClient\n}\n\n//nolint:gocyclo,cyclop,gocognit\nfunc (d *talosImageFactoryExtensionsVersionsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {\n\tif d.imageFactoryClient == nil {\n\t\tresp.Diagnostics.AddError(\"image factory client is not configured\", \"Please report this issue to the provider developers.\")\n\n\t\treturn\n\t}\n\n\tvar config talosImageFactoryExtensionsVersionsDataSourceModelV0\n\n\tresp.Diagnostics.Append(req.Config.Get(ctx, &config)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif config.TalosVersion.IsNull() || config.TalosVersion.IsUnknown() {\n\t\treturn\n\t}\n\n\textensionsInfo, err := d.imageFactoryClient.ExtensionsVersions(ctx, config.TalosVersion.ValueString())\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to get talos extensions versions\", err.Error())\n\n\t\treturn\n\t}\n\n\tvar exactNames, names []string\n\tif config.ExactFilters != nil && !config.ExactFilters.Names.IsNull() && !config.ExactFilters.Names.IsUnknown() {\n\t\tresp.Diagnostics.Append(config.ExactFilters.Names.ElementsAs(ctx, &exactNames, true)...)\n\n\t\tif resp.Diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif config.Filters != nil && !config.Filters.Names.IsNull() && !config.Filters.Names.IsUnknown() {\n\t\tresp.Diagnostics.Append(config.Filters.Names.ElementsAs(ctx, &names, true)...)\n\n\t\tif resp.Diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif len(exactNames) > 0 || len(names) > 0 {\n\t\textensionsInfo = xslices.Filter(extensionsInfo, func(e client.ExtensionInfo) bool {\n\t\t\tif len(exactNames) > 0 {\n\t\t\t\tif slices.Contains(exactNames, e.Name) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif len(names) > 0 {\n\t\t\t\tfor _, n := range names {\n\t\t\t\t\tif strings.Contains(e.Name, n) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false\n\t\t})\n\t}\n\n\ttfExtensionsInfo := xslices.Map(extensionsInfo, func(e client.ExtensionInfo) extensionInfo {\n\t\treturn extensionInfo{\n\t\t\tName:        types.StringValue(e.Name),\n\t\t\tRef:         types.StringValue(e.Ref),\n\t\t\tDigest:      types.StringValue(e.Digest),\n\t\t\tAuthor:      types.StringValue(e.Author),\n\t\t\tDescription: types.StringValue(e.Description),\n\t\t}\n\t})\n\n\tresp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(\"id\"), \"extensions_info\")...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tresp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(\"extensions_info\"), &tfExtensionsInfo)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_image_factory_extensions_versions_data_source_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n)\n\nfunc TestAccTalosImageFactoryExtensionsVersionsDataSource(t *testing.T) {\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: testAccTalosImageFactoryExtensionsVersionsDataSourceConfig(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_extensions_versions.this\", \"extensions_info.0.name\", \"siderolabs/amdgpu-firmware\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tConfig: testAccTalosImageFactoryExtensionsVersionsDataSourceConfigWithFilters(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_extensions_versions.this\", \"extensions_info.#\", \"5\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_extensions_versions.this\", \"extensions_info.0.name\", \"siderolabs/nvidia-container-toolkit\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tConfig: testAccTalosImageFactoryExtensionsVersionsDataSourceConfigWithExactFilters(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_extensions_versions.this\", \"extensions_info.#\", \"1\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_extensions_versions.this\", \"extensions_info.0.name\", \"siderolabs/tailscale\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosImageFactoryExtensionsVersionsDataSourceConfig() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_extensions_versions\" \"this\" {\n\ttalos_version = \"v1.7.0\"\n}\n`\n}\n\nfunc testAccTalosImageFactoryExtensionsVersionsDataSourceConfigWithFilters() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_extensions_versions\" \"this\" {\n\ttalos_version = \"v1.7.0\"\n\tfilters = {\n\t\tnames = [\n\t\t\t\"nvidia\",\n\t\t\t\"tailscale\"\n\t\t]\n\t}\n}\n`\n}\n\nfunc testAccTalosImageFactoryExtensionsVersionsDataSourceConfigWithExactFilters() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_extensions_versions\" \"this\" {\n\ttalos_version = \"v1.7.0\"\n\texact_filters = {\n\t\tnames = [\n\t\t\t\"nvidia\",\n\t\t\t\"siderolabs/tailscale\"\n\t\t]\n\t}\n}\n`\n}\n"
  },
  {
    "path": "pkg/talos/talos_image_factory_overlays_versions_data_source.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework/attr\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/path\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/siderolabs/gen/xslices\"\n\t\"github.com/siderolabs/image-factory/pkg/client\"\n)\n\ntype talosImageFactoryOverlaysVersionsDataSource struct {\n\timageFactoryClient *client.Client\n}\n\ntype talosImageFactoryOverlaysVersionsDataSourceModelV0 struct {\n\tID           types.String                             `tfsdk:\"id\"`\n\tTalosVersion types.String                             `tfsdk:\"talos_version\"`\n\tFilters      *talosImageFactoryOverlaysVersionsFilter `tfsdk:\"filters\"`\n\tOverlaysInfo []overlayInfo                            `tfsdk:\"overlays_info\"`\n}\n\ntype talosImageFactoryOverlaysVersionsFilter struct {\n\tName types.String `tfsdk:\"name\"`\n}\n\ntype overlayInfo struct {\n\tName   types.String `tfsdk:\"name\"`\n\tImage  types.String `tfsdk:\"image\"`\n\tRef    types.String `tfsdk:\"ref\"`\n\tDigest types.String `tfsdk:\"digest\"`\n}\n\nvar _ datasource.DataSourceWithConfigure = &talosImageFactoryOverlaysVersionsDataSource{}\n\n// NewTalosImageFactoryOverlaysVersionsDataSource implements the datasource.DataSource interface.\nfunc NewTalosImageFactoryOverlaysVersionsDataSource() datasource.DataSource {\n\treturn &talosImageFactoryOverlaysVersionsDataSource{}\n}\n\nfunc (d *talosImageFactoryOverlaysVersionsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_image_factory_overlays_versions\"\n}\n\nfunc (d *talosImageFactoryOverlaysVersionsDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"The image factory overlays versions data source provides a list of available overlays for a specific talos version from the image factory.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tComputed: true,\n\t\t\t},\n\t\t\t\"talos_version\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The talos version to get overlays for.\",\n\t\t\t},\n\t\t\t\"filters\": schema.SingleNestedAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"The filter to apply to the overlays list.\",\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"name\": schema.StringAttribute{\n\t\t\t\t\t\tOptional:    true,\n\t\t\t\t\t\tDescription: \"The name of the overlay to filter by.\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"overlays_info\": schema.ListAttribute{\n\t\t\t\tElementType: types.ObjectType{\n\t\t\t\t\tAttrTypes: map[string]attr.Type{\n\t\t\t\t\t\t\"name\":   types.StringType,\n\t\t\t\t\t\t\"image\":  types.StringType,\n\t\t\t\t\t\t\"ref\":    types.StringType,\n\t\t\t\t\t\t\"digest\": types.StringType,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The list of available extensions for the specified talos version.\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (d *talosImageFactoryOverlaysVersionsDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {\n\tif req.ProviderData == nil {\n\t\treturn\n\t}\n\n\timageFactoryClient, ok := req.ProviderData.(*client.Client)\n\tif !ok {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to get image factory client\",\n\t\t\tfmt.Sprintf(\"Expected *client.Client, got: %T. Please report this issue to the provider developers.\", req.ProviderData),\n\t\t)\n\n\t\treturn\n\t}\n\n\td.imageFactoryClient = imageFactoryClient\n}\n\nfunc (d *talosImageFactoryOverlaysVersionsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {\n\tif d.imageFactoryClient == nil {\n\t\tresp.Diagnostics.AddError(\"image factory client is not configured\", \"Please report this issue to the provider developers.\")\n\n\t\treturn\n\t}\n\n\tvar config talosImageFactoryOverlaysVersionsDataSourceModelV0\n\n\tresp.Diagnostics.Append(req.Config.Get(ctx, &config)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif config.TalosVersion.IsNull() || config.TalosVersion.IsUnknown() {\n\t\treturn\n\t}\n\n\toverlaysInfo, err := d.imageFactoryClient.OverlaysVersions(ctx, config.TalosVersion.ValueString())\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to get talos overlays versions\", err.Error())\n\n\t\treturn\n\t}\n\n\tif config.Filters != nil && !config.Filters.Name.IsNull() && !config.Filters.Name.IsUnknown() {\n\t\toverlaysInfo = xslices.Filter(overlaysInfo, func(e client.OverlayInfo) bool {\n\t\t\treturn strings.Contains(e.Name, config.Filters.Name.ValueString())\n\t\t})\n\t}\n\n\ttfOverlaysInfo := xslices.Map(overlaysInfo, func(e client.OverlayInfo) overlayInfo {\n\t\treturn overlayInfo{\n\t\t\tName:   types.StringValue(e.Name),\n\t\t\tImage:  types.StringValue(e.Image),\n\t\t\tRef:    types.StringValue(e.Ref),\n\t\t\tDigest: types.StringValue(e.Digest),\n\t\t}\n\t})\n\n\tresp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(\"id\"), \"overlays_info\")...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tresp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(\"overlays_info\"), &tfOverlaysInfo)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_image_factory_overlays_versions_data_source_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n)\n\nfunc TestAccTalosImageFactoryOverlaysVersionsDataSource(t *testing.T) {\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: testAccTalosImageFactoryOverlaysVersionsDataSourceConfig(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_overlays_versions.this\", \"overlays_info.0.name\", \"rpi_generic\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tConfig: testAccTalosImageFactoryOverlaysVersionsDataSourceConfigWithFilters(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_overlays_versions.this\", \"overlays_info.#\", \"1\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_overlays_versions.this\", \"overlays_info.0.name\", \"rock4cplus\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosImageFactoryOverlaysVersionsDataSourceConfig() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_overlays_versions\" \"this\" {\n\ttalos_version = \"v1.7.0\"\n}\n`\n}\n\nfunc testAccTalosImageFactoryOverlaysVersionsDataSourceConfigWithFilters() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_overlays_versions\" \"this\" {\n\ttalos_version = \"v1.7.0\"\n\tfilters = {\n\t\tname = \"rock4cplus\"\n\t}\n}\n`\n}\n"
  },
  {
    "path": "pkg/talos/talos_image_factory_schematic_resource.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework/resource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/siderolabs/image-factory/pkg/client\"\n\t\"github.com/siderolabs/image-factory/pkg/schematic\"\n\t\"go.yaml.in/yaml/v4\"\n)\n\ntype talosImageFactorySchematicResource struct {\n\timageFactoryClient *client.Client\n}\n\nvar (\n\t_ resource.Resource              = &talosImageFactorySchematicResource{}\n\t_ resource.ResourceWithConfigure = &talosImageFactorySchematicResource{}\n)\n\nvar schematicAttributeMarkdownDescription = `\nThe schematic yaml respresentation to generate the image.\n\nIf not set, a vanilla Talos image schematic will be generated.\n\n> Refer to [image-factory](https://github.com/siderolabs/image-factory?tab=readme-ov-file#post-schematics) for the schema.\n`\n\ntype talosImageFactorySchematicResourceModelV0 struct {\n\tID        types.String `tfsdk:\"id\"`\n\tSchematic types.String `tfsdk:\"schematic\"`\n}\n\n// NewTalosImageFactorySchematicResource implements the resource.Resource interface.\nfunc NewTalosImageFactorySchematicResource() resource.Resource {\n\treturn &talosImageFactorySchematicResource{}\n}\n\nfunc (r *talosImageFactorySchematicResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_image_factory_schematic\"\n}\n\nfunc (r *talosImageFactorySchematicResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"The image factory schematic resource allows you to create a schematic for a Talos image.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The unique ID of the schematic, returned from Image Factory.\",\n\t\t\t},\n\t\t\t\"schematic\": schema.StringAttribute{\n\t\t\t\tOptional:            true,\n\t\t\t\tMarkdownDescription: schematicAttributeMarkdownDescription,\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (r *talosImageFactorySchematicResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {\n\tif req.ProviderData == nil {\n\t\treturn\n\t}\n\n\timageFactoryClient, ok := req.ProviderData.(*client.Client)\n\tif !ok {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to get image factory client\",\n\t\t\t\"Expected *client.Client, got: %T. Please report this issue to the provider developers.\",\n\t\t)\n\n\t\treturn\n\t}\n\n\tr.imageFactoryClient = imageFactoryClient\n}\n\nfunc (r *talosImageFactorySchematicResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {\n\tvar config talosImageFactorySchematicResourceModelV0\n\n\tresp.Diagnostics.Append(req.Config.Get(ctx, &config)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar schematic schematic.Schematic\n\n\tif err := yaml.Unmarshal([]byte(config.Schematic.ValueString()), &schematic); err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to unmarshal schematic\", err.Error())\n\n\t\treturn\n\t}\n\n\tschematicID, err := r.imageFactoryClient.SchematicCreate(ctx, schematic)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to create schematic\", err.Error())\n\n\t\treturn\n\t}\n\n\tconfig.ID = basetypes.NewStringValue(schematicID)\n\n\tresp.Diagnostics.Append(resp.State.Set(ctx, &config)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n\nfunc (r *talosImageFactorySchematicResource) Delete(_ context.Context, _ resource.DeleteRequest, _ *resource.DeleteResponse) {\n}\n\nfunc (r *talosImageFactorySchematicResource) Read(_ context.Context, _ resource.ReadRequest, _ *resource.ReadResponse) {\n}\n\nfunc (r *talosImageFactorySchematicResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {\n\tvar plan talosImageFactorySchematicResourceModelV0\n\n\tdiags := req.Plan.Get(ctx, &plan)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar schematic schematic.Schematic\n\n\tif err := yaml.Unmarshal([]byte(plan.Schematic.ValueString()), &schematic); err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to unmarshal schematic\", err.Error())\n\n\t\treturn\n\t}\n\n\tschematicID, err := r.imageFactoryClient.SchematicCreate(ctx, schematic)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to update schematic\", err.Error())\n\n\t\treturn\n\t}\n\n\tplan.ID = basetypes.NewStringValue(schematicID)\n\n\t// Set state to fully populated data\n\tresp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_image_factory_schematic_resource_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n)\n\nfunc TestAccTalosImageFactorySchematicResource(t *testing.T) {\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t// vanilla image\n\t\t\t{\n\t\t\t\tConfig: testAccTalosTalosImageFactorySchematicConfig(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_image_factory_schematic.this\", \"id\", \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// empty schematic\n\t\t\t{\n\t\t\t\tConfig: testAccTalosTalosImageFactorySchematicEmptySchematicConfig(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_image_factory_schematic.this\", \"id\", \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// empty customization\n\t\t\t{\n\t\t\t\tConfig: testAccTalosTalosImageFactorySchematicEmptyCustomizationConfig(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_image_factory_schematic.this\", \"id\", \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// vanilla image\n\t\t\t{\n\t\t\t\tConfig: testAccTalosTalosImageFactorySchematicConfig(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_image_factory_schematic.this\", \"id\", \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// known extension\n\t\t\t{\n\t\t\t\tConfig: testAccTalosTalosImageFactorySchematicKnownExtensionConfig(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_image_factory_schematic.this\", \"id\", \"d01dbf04a51b44a41d62b7c9692da0a74889277651600da6b602582654e4b402\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosTalosImageFactorySchematicConfig() string {\n\treturn `\nprovider \"talos\" {}\n\nresource \"talos_image_factory_schematic\" \"this\" {}\n`\n}\n\nfunc testAccTalosTalosImageFactorySchematicEmptySchematicConfig() string {\n\treturn `\nprovider \"talos\" {}\n\nresource \"talos_image_factory_schematic\" \"this\" {\n\tschematic = yamlencode({})\n}\n`\n}\n\nfunc testAccTalosTalosImageFactorySchematicEmptyCustomizationConfig() string {\n\treturn `\nprovider \"talos\" {}\n\nresource \"talos_image_factory_schematic\" \"this\" {\n\tschematic = yamlencode(\n\t\t{\n\t\t\tcustomization = {}\n\t\t}\n\t)\n}\n`\n}\n\nfunc testAccTalosTalosImageFactorySchematicKnownExtensionConfig() string {\n\treturn `\nprovider \"talos\" {}\n\nresource \"talos_image_factory_schematic\" \"this\" {\n\tschematic = yamlencode(\n\t\t{\n\t\t\tcustomization = {\n\t\t\t\tsystemExtensions = {\n\t\t\t\t\tofficialExtensions = [\"siderolabs/amdgpu-firmware\"]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t)\n}\n`\n}\n"
  },
  {
    "path": "pkg/talos/talos_image_factory_urls_data_source.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"slices\"\n\t\"strings\"\n\t\"text/template\"\n\n\t\"github.com/blang/semver/v4\"\n\t\"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/path\"\n\t\"github.com/hashicorp/terraform-plugin-framework/schema/validator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/siderolabs/gen/xslices\"\n\t\"github.com/siderolabs/image-factory/pkg/client\"\n\t\"github.com/siderolabs/talos/pkg/machinery/platforms\"\n)\n\ntype talosImageFactoryURLSDataSource struct {\n\timageFactoryClient *client.Client\n}\n\nvar _ datasource.DataSource = &talosImageFactoryURLSDataSource{}\n\nvar (\n\tmetalPlatforms                      = []string{\"metal\"}\n\tcloudPlatforms                      = xslices.Map(platforms.CloudPlatforms(), func(platform platforms.Platform) string { return platform.Name })\n\tsbcs                                = xslices.Map(platforms.SBCs(), func(platform platforms.SBC) string { return platform.Name })\n\tallPlatforms                        = slices.Concat(metalPlatforms, cloudPlatforms)\n\tplatformMarkdownDescriptionTemplate = `\nThe platform for which the URLs are generated.\n\n\t#### Metal\n\n\t\t- metal\n\n    #### Cloud Platforms\n\n        {{- range .FactoryPlatforms }}\n        - {{ . }}\n        {{- end }}\n`\n\tsbcMarkdownDescriptionTemplate = `\nThe SBC's (Single Board Copmuters) for which the url are generated.\n\n    #### Single Board Computers\n\n        {{- range .SBCs }}\n        - {{ . }}\n        {{- end }}\n`\n)\n\nvar (\n\t_ datasource.DataSource              = &talosImageFactoryURLSDataSource{}\n\t_ datasource.DataSourceWithConfigure = &talosImageFactoryURLSDataSource{}\n)\n\ntype talosImageFactoryURLSDataSourceModelV0 struct {\n\tID           types.String `tfsdk:\"id\"`\n\tArchitecture types.String `tfsdk:\"architecture\"`\n\tTalosVersion types.String `tfsdk:\"talos_version\"`\n\tSchematicID  types.String `tfsdk:\"schematic_id\"`\n\tPlatform     types.String `tfsdk:\"platform\"`\n\tSBC          types.String `tfsdk:\"sbc\"`\n\tURLs         urls         `tfsdk:\"urls\"`\n}\n\ntype urls struct {\n\tInstaller           types.String `tfsdk:\"installer\"`\n\tInstallerSecureboot types.String `tfsdk:\"installer_secureboot\"`\n\tISO                 types.String `tfsdk:\"iso\"`\n\tISOSecureboot       types.String `tfsdk:\"iso_secureboot\"`\n\tDiskImage           types.String `tfsdk:\"disk_image\"`\n\tDiskImageSecureboot types.String `tfsdk:\"disk_image_secureboot\"`\n\tPXE                 types.String `tfsdk:\"pxe\"`\n\tKernel              types.String `tfsdk:\"kernel\"`\n\tKernelCommandLine   types.String `tfsdk:\"kernel_command_line\"`\n\tInitramfs           types.String `tfsdk:\"initramfs\"`\n\tUKI                 types.String `tfsdk:\"uki\"`\n}\n\n// NewTalosImageFactoryURLSDataSource implements the datasource.Datasource interface.\nfunc NewTalosImageFactoryURLSDataSource() datasource.DataSource {\n\treturn &talosImageFactoryURLSDataSource{}\n}\n\nfunc (d *talosImageFactoryURLSDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_image_factory_urls\"\n}\n\nfunc (d *talosImageFactoryURLSDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {\n\tvar platformMarkdownDescription strings.Builder\n\n\ttemplate.Must(template.New(\"platformMarkdownDescription\").Parse(platformMarkdownDescriptionTemplate)).Execute(&platformMarkdownDescription, struct { //nolint:errcheck\n\t\tFactoryPlatforms []string\n\t}{\n\t\tFactoryPlatforms: cloudPlatforms,\n\t})\n\n\tvar sbcMarkdownDescription strings.Builder\n\n\ttemplate.Must(template.New(\"sbcMarkdownDescription\").Parse(sbcMarkdownDescriptionTemplate)).Execute(&sbcMarkdownDescription, struct { //nolint:errcheck\n\t\tSBCs []string\n\t}{\n\t\tSBCs: sbcs,\n\t})\n\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"Generates URLs for different assets supported by the Talos image factory.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tComputed: true,\n\t\t\t},\n\t\t\t\"architecture\": schema.StringAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The platform architecture for which the URLs are generated. Defaults to amd64.\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tstringvalidator.OneOf(\"amd64\", \"arm64\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"talos_version\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The Talos version for which the URLs are generated.\",\n\t\t\t},\n\t\t\t\"schematic_id\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The schematic ID for which the URLs are generated.\",\n\t\t\t},\n\t\t\t\"platform\": schema.StringAttribute{\n\t\t\t\tOptional:            true,\n\t\t\t\tMarkdownDescription: platformMarkdownDescription.String(),\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tstringvalidator.All(\n\t\t\t\t\t\tstringvalidator.OneOf(allPlatforms...),\n\t\t\t\t\t\tstringvalidator.ExactlyOneOf(path.Expressions{\n\t\t\t\t\t\t\tpath.MatchRoot(\"sbc\"),\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\t\"sbc\": schema.StringAttribute{\n\t\t\t\tOptional:            true,\n\t\t\t\tMarkdownDescription: sbcMarkdownDescription.String(),\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tstringvalidator.All(\n\t\t\t\t\t\tstringvalidator.OneOf(sbcs...),\n\t\t\t\t\t\tstringvalidator.ExactlyOneOf(path.Expressions{\n\t\t\t\t\t\t\tpath.MatchRoot(\"platform\"),\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\t\"urls\": schema.SingleNestedAttribute{\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The URLs for different assets supported by the Talos image factory. If the URL is not available for a specific asset, it will be an empty string.\",\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"installer\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The URL for the installer image.\",\n\t\t\t\t\t},\n\t\t\t\t\t\"installer_secureboot\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The URL for the installer image with secure boot.\",\n\t\t\t\t\t},\n\t\t\t\t\t\"iso\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The URL for the ISO image.\",\n\t\t\t\t\t},\n\t\t\t\t\t\"iso_secureboot\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The URL for the ISO image with secure boot.\",\n\t\t\t\t\t},\n\t\t\t\t\t\"disk_image\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The URL for the disk image.\",\n\t\t\t\t\t},\n\t\t\t\t\t\"disk_image_secureboot\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The URL for the disk image with secure boot.\",\n\t\t\t\t\t},\n\t\t\t\t\t\"pxe\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The URL for the PXE image.\",\n\t\t\t\t\t},\n\t\t\t\t\t\"kernel\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The URL for the kernel image.\",\n\t\t\t\t\t},\n\t\t\t\t\t\"kernel_command_line\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The URL for the kernel command line.\",\n\t\t\t\t\t},\n\t\t\t\t\t\"initramfs\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The URL for the initramfs image.\",\n\t\t\t\t\t},\n\t\t\t\t\t\"uki\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The URL for the UKI image.\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (d *talosImageFactoryURLSDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {\n\tif req.ProviderData == nil {\n\t\treturn\n\t}\n\n\timageFactoryClient, ok := req.ProviderData.(*client.Client)\n\tif !ok {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to get image factory client\",\n\t\t\tfmt.Sprintf(\"Expected *client.Client, got: %T. Please report this issue to the provider developers.\", req.ProviderData),\n\t\t)\n\n\t\treturn\n\t}\n\n\td.imageFactoryClient = imageFactoryClient\n}\n\nfunc (d *talosImageFactoryURLSDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {\n\tif d.imageFactoryClient == nil {\n\t\tresp.Diagnostics.AddError(\"image factory client is not configured\", \"Please report this issue to the provider developers.\")\n\n\t\treturn\n\t}\n\n\tvar obj types.Object\n\n\tresp.Diagnostics.Append(req.Config.Get(ctx, &obj)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar config talosImageFactoryURLSDataSourceModelV0\n\n\tresp.Diagnostics.Append(obj.As(ctx, &config, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif config.Architecture.IsNull() {\n\t\tconfig.Architecture = basetypes.NewStringValue(\"amd64\")\n\t}\n\n\tarchitecture := config.Architecture.ValueString()\n\tplatform := config.Platform.ValueString()\n\ttalosVersion := \"v\" + strings.TrimPrefix(config.TalosVersion.ValueString(), \"v\")\n\n\tif _, err := semver.ParseTolerant(talosVersion); err != nil {\n\t\tresp.Diagnostics.AddError(\"talos_version is not valid\", \"The provided version is not a valid semantic version.\")\n\n\t\treturn\n\t}\n\n\tschematicID := config.SchematicID.ValueString()\n\n\turi, err := url.Parse(d.imageFactoryClient.BaseURL())\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to parse image factory base URL\", err.Error())\n\n\t\treturn\n\t}\n\n\turlsData := urls{\n\t\tInstaller: basetypes.NewStringValue(fmt.Sprintf(\"%s/%s-installer/%s:%s\", uri.Host, platform, schematicID, talosVersion)),\n\t}\n\n\tswitch platform {\n\tcase \"metal\":\n\t\tplatformData := platforms.MetalPlatform()\n\n\t\turlsData.InstallerSecureboot = basetypes.NewStringValue(fmt.Sprintf(\"%s/%s-installer-secureboot/%s:%s\", uri.Host, platform, schematicID, talosVersion))\n\t\turlsData.ISO = basetypes.NewStringValue(fmt.Sprintf(\"%s/image/%s/%s/%s\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion, platformData.ISOPath(architecture)))\n\t\turlsData.ISOSecureboot = basetypes.NewStringValue(fmt.Sprintf(\"%s/image/%s/%s/%s\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion, platformData.SecureBootISOPath(architecture)))\n\t\turlsData.DiskImage = basetypes.NewStringValue(fmt.Sprintf(\"%s/image/%s/%s/%s\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion, platformData.DiskImageDefaultPath(architecture)))\n\t\turlsData.DiskImageSecureboot = basetypes.NewStringValue(\n\t\t\tfmt.Sprintf(\"%s/image/%s/%s/%s\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion, platformData.SecureBootDiskImageDefaultPath(architecture)),\n\t\t)\n\t\turlsData.PXE = basetypes.NewStringValue(fmt.Sprintf(\"%s://pxe.%s/pxe/%s/%s/%s\", uri.Scheme, uri.Host, schematicID, talosVersion, platformData.PXEScriptPath(architecture)))\n\t\turlsData.Kernel = basetypes.NewStringValue(fmt.Sprintf(\"%s/image/%s/%s/%s\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion, platformData.KernelPath(architecture)))\n\t\turlsData.KernelCommandLine = basetypes.NewStringValue(fmt.Sprintf(\"%s/image/%s/%s/%s\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion, platformData.CmdlinePath(architecture)))\n\t\turlsData.Initramfs = basetypes.NewStringValue(fmt.Sprintf(\"%s/image/%s/%s/%s\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion, platformData.InitramfsPath(architecture)))\n\t\turlsData.UKI = basetypes.NewStringValue(fmt.Sprintf(\"%s/image/%s/%s/%s\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion, platformData.SecureBootUKIPath(architecture)))\n\tcase \"\": // empty platform means it's an SBC\n\t\turlsData.Installer = basetypes.NewStringValue(fmt.Sprintf(\"%s/metal-installer/%s:%s\", uri.Host, schematicID, talosVersion))\n\t\turlsData.DiskImage = basetypes.NewStringValue(fmt.Sprintf(\"%s/image/%s/%s/metal-arm64.raw.xz\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion))\n\tdefault:\n\t\tplatformData := xslices.Filter(platforms.CloudPlatforms(), func(p platforms.Platform) bool { return p.Name == platform })\n\n\t\tif len(platformData) != 1 {\n\t\t\tresp.Diagnostics.AddError(\"failed to find platform\", platform)\n\n\t\t\treturn\n\t\t}\n\n\t\tif platformData[0].SecureBootSupported {\n\t\t\turlsData.InstallerSecureboot = basetypes.NewStringValue(fmt.Sprintf(\"%s/%s-installer-secureboot/%s:%s\", uri.Host, platform, schematicID, talosVersion))\n\t\t}\n\n\t\tfor _, bootMethod := range platformData[0].BootMethods {\n\t\t\tswitch bootMethod {\n\t\t\tcase platforms.BootMethodDiskImage:\n\t\t\t\turlsData.DiskImage = basetypes.NewStringValue(fmt.Sprintf(\"%s/image/%s/%s/%s\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion, platformData[0].DiskImageDefaultPath(architecture))) //nolint:lll\n\t\t\t\tif platformData[0].SecureBootSupported {\n\t\t\t\t\turlsData.DiskImageSecureboot = basetypes.NewStringValue(fmt.Sprintf(\"%s/image/%s/%s/%s\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion, platformData[0].SecureBootDiskImageDefaultPath(architecture))) //nolint:lll\n\t\t\t\t}\n\t\t\tcase platforms.BootMethodPXE:\n\t\t\t\turlsData.PXE = basetypes.NewStringValue(fmt.Sprintf(\"%s://pxe.%s/pxe/%s/%s/%s\", uri.Scheme, uri.Host, schematicID, talosVersion, platformData[0].PXEScriptPath(architecture))) //nolint:lll\n\t\t\tcase platforms.BootMethodISO:\n\t\t\t\turlsData.ISO = basetypes.NewStringValue(fmt.Sprintf(\"%s/image/%s/%s/%s\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion, platformData[0].ISOPath(architecture)))\n\t\t\t\tif platformData[0].SecureBootSupported {\n\t\t\t\t\turlsData.ISOSecureboot = basetypes.NewStringValue(fmt.Sprintf(\"%s/image/%s/%s/%s\", d.imageFactoryClient.BaseURL(), schematicID, talosVersion, platformData[0].SecureBootISOPath(architecture))) //nolint:lll\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconfig.ID = basetypes.NewStringValue(config.ID.ValueString())\n\tconfig.URLs = urlsData\n\n\tresp.Diagnostics.Append(resp.State.Set(ctx, &config)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_image_factory_urls_data_source_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"regexp\"\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n)\n\nfunc TestAccTalosImageFactoryURLsDataSource(t *testing.T) {\n\tresource.Test(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig:      testAccTalosImageFactoryURLsBothSBCAndPlatformNotSetConfig(),\n\t\t\t\tExpectError: regexp.MustCompile(\"Invalid Attribute Combination\"),\n\t\t\t},\n\t\t\t{\n\t\t\t\tConfig:      testAccTalosImageFactoryURLsBothSBCAndPlatformSetConfig(),\n\t\t\t\tExpectError: regexp.MustCompile(\"Invalid Attribute Combination\"),\n\t\t\t},\n\t\t\t// Invalid Version\n\t\t\t{\n\t\t\t\tConfig:      testAccTalosImageFactoryURLsInvalidVersionConfig(),\n\t\t\t\tExpectError: regexp.MustCompile(\"talos_version is not valid\"),\n\t\t\t},\n\t\t},\n\t})\n\n\t//nolint:lll\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t// metal platform\n\t\t\t{\n\t\t\t\tConfig: testAccTalosImageFactoryURLsMetalPlatformConfig(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.installer\", \"factory.talos.dev/metal-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.7.5\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.installer_secureboot\", \"factory.talos.dev/metal-installer-secureboot/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.7.5\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.iso\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/metal-amd64.iso\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.iso_secureboot\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/metal-amd64-secureboot.iso\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.disk_image\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/metal-amd64.raw.zst\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.disk_image_secureboot\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/metal-amd64-secureboot.raw.zst\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.pxe\", \"https://pxe.factory.talos.dev/pxe/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/metal-amd64\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.kernel\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/kernel-amd64\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.kernel_command_line\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/cmdline-metal-amd64\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.initramfs\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/initramfs-amd64.xz\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.uki\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/metal-amd64-secureboot-uki.efi\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// metal platform arm64\n\t\t\t{\n\t\t\t\tConfig: testAccTalosImageFactoryURLsMetalPlatformArm64Config(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.installer\", \"factory.talos.dev/metal-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.7.5\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.installer_secureboot\", \"factory.talos.dev/metal-installer-secureboot/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.7.5\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.iso\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/metal-arm64.iso\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.iso_secureboot\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/metal-arm64-secureboot.iso\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.disk_image\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/metal-arm64.raw.zst\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.disk_image_secureboot\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/metal-arm64-secureboot.raw.zst\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.pxe\", \"https://pxe.factory.talos.dev/pxe/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/metal-arm64\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.kernel\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/kernel-arm64\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.kernel_command_line\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/cmdline-metal-arm64\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.initramfs\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/initramfs-arm64.xz\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.uki\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/metal-arm64-secureboot-uki.efi\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// aws platform\n\t\t\t{\n\t\t\t\tConfig: testAccTalosImageFactoryURLsAWSPlatformConfig(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.installer\", \"factory.talos.dev/aws-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.7.5\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.installer_secureboot\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.iso\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.iso_secureboot\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.disk_image\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/aws-amd64.raw.xz\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.disk_image_secureboot\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.pxe\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.kernel\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.kernel_command_line\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.initramfs\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.uki\"),\n\t\t\t\t),\n\t\t\t},\n\n\t\t\t// nocloud platform\n\t\t\t{\n\t\t\t\tConfig: testAccTalosImageFactoryURLsNoCloudPlatformConfig(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.installer\", \"factory.talos.dev/nocloud-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.7.5\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.installer_secureboot\", \"factory.talos.dev/nocloud-installer-secureboot/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.7.5\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.iso\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/nocloud-amd64.iso\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.iso_secureboot\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/nocloud-amd64-secureboot.iso\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.disk_image\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/nocloud-amd64.raw.xz\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.disk_image_secureboot\", \"https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/nocloud-amd64-secureboot.raw.xz\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.pxe\", \"https://pxe.factory.talos.dev/pxe/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.5/nocloud-amd64\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.kernel\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.kernel_command_line\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.initramfs\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.uki\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// rpigeneric sbc\n\t\t\t{\n\t\t\t\tConfig: testAccTalosImageFactoryURLsSBCConfig(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.installer\", \"factory.talos.dev/metal-installer/ee21ef4a5ef808a9b7484cc0dda0f25075021691c8c09a276591eedb638ea1f9:v1.7.5\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.installer_secureboot\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.iso\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.iso_secureboot\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.disk_image\", \"https://factory.talos.dev/image/ee21ef4a5ef808a9b7484cc0dda0f25075021691c8c09a276591eedb638ea1f9/v1.7.5/metal-arm64.raw.xz\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.disk_image_secureboot\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.pxe\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.kernel\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.kernel_command_line\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.initramfs\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_image_factory_urls.this\", \"urls.uki\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosImageFactoryURLsBothSBCAndPlatformNotSetConfig() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_urls\" \"this\" {\n\ttalos_version = \"v1.7.0\"\n\tschematic_id = \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"\n}\n`\n}\n\nfunc testAccTalosImageFactoryURLsBothSBCAndPlatformSetConfig() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_urls\" \"this\" {\n\ttalos_version = \"v1.7.0\"\n\tschematic_id = \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"\n\tplatform = \"metal\"\n\tsbc = \"rpi_generic\"\n}\n`\n}\n\nfunc testAccTalosImageFactoryURLsMetalPlatformConfig() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_urls\" \"this\" {\n\ttalos_version = \"1.7.5\"\n\tschematic_id = \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"\n\tplatform = \"metal\"\n}\n`\n}\n\nfunc testAccTalosImageFactoryURLsMetalPlatformArm64Config() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_urls\" \"this\" {\n\tarchitecture = \"arm64\"\n\ttalos_version = \"v1.7.5\"\n\tschematic_id = \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"\n\tplatform = \"metal\"\n}\n`\n}\n\nfunc testAccTalosImageFactoryURLsAWSPlatformConfig() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_urls\" \"this\" {\n\ttalos_version = \"v1.7.5\"\n\tschematic_id = \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"\n\tplatform = \"aws\"\n}\n`\n}\n\nfunc testAccTalosImageFactoryURLsNoCloudPlatformConfig() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_urls\" \"this\" {\n\ttalos_version = \"v1.7.5\"\n\tschematic_id = \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"\n\tplatform = \"nocloud\"\n}\n`\n}\n\nfunc testAccTalosImageFactoryURLsSBCConfig() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_urls\" \"this\" {\n\ttalos_version = \"v1.7.5\"\n\tschematic_id = \"ee21ef4a5ef808a9b7484cc0dda0f25075021691c8c09a276591eedb638ea1f9\"\n\tsbc = \"rpi_generic\"\n}\n`\n}\n\nfunc testAccTalosImageFactoryURLsInvalidVersionConfig() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_urls\" \"this\" {\n\ttalos_version = \"invalid_version\"\n\tschematic_id = \"376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba\"\n\tplatform = \"metal\"\n}\n`\n}\n"
  },
  {
    "path": "pkg/talos/talos_image_factory_versions_data_source.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/blang/semver/v4\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/siderolabs/image-factory/pkg/client\"\n)\n\ntype talosImageFactoryVersionsDataSource struct {\n\timageFactoryClient *client.Client\n}\n\ntype talosImageFactoryVersionsDataSourceModelV0 struct {\n\tID            types.String                     `tfsdk:\"id\"`\n\tFilters       *talosImageFactoryVersionsFilter `tfsdk:\"filters\"`\n\tTalosVersions []string                         `tfsdk:\"talos_versions\"`\n}\n\ntype talosImageFactoryVersionsFilter struct {\n\tStableVersionOnly types.Bool `tfsdk:\"stable_versions_only\"`\n}\n\nvar _ datasource.DataSourceWithConfigure = &talosImageFactoryVersionsDataSource{}\n\n// NewTalosImageFactoryVersionsDataSource implements the datasource.DataSource interface.\nfunc NewTalosImageFactoryVersionsDataSource() datasource.DataSource {\n\treturn &talosImageFactoryVersionsDataSource{}\n}\n\nfunc (d *talosImageFactoryVersionsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_image_factory_versions\"\n}\n\nfunc (d *talosImageFactoryVersionsDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"The image factory versions data source provides a list of available talos versions from the image factory.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tComputed: true,\n\t\t\t},\n\t\t\t\"talos_versions\": schema.ListAttribute{\n\t\t\t\tElementType: types.StringType,\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The list of available talos versions.\",\n\t\t\t},\n\t\t\t\"filters\": schema.SingleNestedAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"The filter to apply to the overlays list.\",\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"stable_versions_only\": schema.BoolAttribute{\n\t\t\t\t\t\tOptional:    true,\n\t\t\t\t\t\tDescription: \"If set to true, only stable versions will be returned. If set to false, all versions will be returned.\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (d *talosImageFactoryVersionsDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {\n\tif req.ProviderData == nil {\n\t\treturn\n\t}\n\n\timageFactoryClient, ok := req.ProviderData.(*client.Client)\n\tif !ok {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to get image factory client\",\n\t\t\tfmt.Sprintf(\"Expected *client.Client, got: %T. Please report this issue to the provider developers.\", req.ProviderData),\n\t\t)\n\n\t\treturn\n\t}\n\n\td.imageFactoryClient = imageFactoryClient\n}\n\nfunc (d *talosImageFactoryVersionsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {\n\tif d.imageFactoryClient == nil {\n\t\tresp.Diagnostics.AddError(\"image factory client is not configured\", \"Please report this issue to the provider developers.\")\n\n\t\treturn\n\t}\n\n\tversions, err := d.imageFactoryClient.Versions(ctx)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to get talos versions\", err.Error())\n\n\t\treturn\n\t}\n\n\tvar config talosImageFactoryVersionsDataSourceModelV0\n\n\tresp.Diagnostics.Append(req.Config.Get(ctx, &config)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif config.Filters != nil && config.Filters.StableVersionOnly.ValueBool() {\n\t\tvar filteredVersions []string\n\n\t\tfor _, version := range versions {\n\t\t\tsemVer, err := semver.Parse(strings.TrimPrefix(version, \"v\"))\n\t\t\tif err != nil {\n\t\t\t\tresp.Diagnostics.AddError(\"failed to parse talos version\", err.Error())\n\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif len(semVer.Pre) > 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tfilteredVersions = append(filteredVersions, version)\n\t\t}\n\n\t\tif resp.Diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\n\t\tversions = filteredVersions\n\t}\n\n\tstate := talosImageFactoryVersionsDataSourceModelV0{\n\t\tID:            basetypes.NewStringValue(\"talos_versions\"),\n\t\tTalosVersions: versions,\n\t}\n\n\tresp.Diagnostics.Append(resp.State.Set(ctx, &state)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_image_factory_versions_data_source_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n\t\"github.com/hashicorp/terraform-plugin-testing/knownvalue\"\n\t\"github.com/hashicorp/terraform-plugin-testing/statecheck\"\n)\n\nfunc TestAccTalosImageFactoryVersionsDataSource(t *testing.T) {\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: testAccTalosImageFactoryVersionsDataSourceConfig(),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_image_factory_versions.this\", \"talos_versions.0\", \"v1.2.0\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tConfig: testAccTalosImageFactoryVersionsDataSourceWithFilterConfig(),\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownOutputValue(\"talos_version\", knownvalue.StringExact(\"v1.13.0\")),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosImageFactoryVersionsDataSourceConfig() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_versions\" \"this\" {}\n`\n}\n\nfunc testAccTalosImageFactoryVersionsDataSourceWithFilterConfig() string {\n\treturn `\nprovider \"talos\" {}\n\ndata \"talos_image_factory_versions\" \"this\" {\n\tfilters = {\n\t\tstable_versions_only = true\n\t}\n}\n\noutput \"talos_version\" {\n\tvalue = data.talos_image_factory_versions.this.talos_versions[length(data.talos_image_factory_versions.this.talos_versions) - 1]\n}\n`\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_bootstrap_resource.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts\"\n\t\"github.com/hashicorp/terraform-plugin-framework/attr\"\n\t\"github.com/hashicorp/terraform-plugin-framework/path\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry\"\n\tmachineapi \"github.com/siderolabs/talos/pkg/machinery/api/machine\"\n\t\"github.com/siderolabs/talos/pkg/machinery/client\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\ntype talosMachineBootstrapResource struct{}\n\nvar (\n\t_ resource.Resource                 = &talosMachineBootstrapResource{}\n\t_ resource.ResourceWithModifyPlan   = &talosMachineBootstrapResource{}\n\t_ resource.ResourceWithUpgradeState = &talosMachineBootstrapResource{}\n\t_ resource.ResourceWithImportState  = &talosMachineBootstrapResource{}\n)\n\ntype talosMachineBootstrapResourceModelV0 struct {\n\tID          types.String `tfsdk:\"id\"`\n\tEndpoint    types.String `tfsdk:\"endpoint\"`\n\tNode        types.String `tfsdk:\"node\"`\n\tTalosConfig types.String `tfsdk:\"talos_config\"`\n}\n\ntype talosMachineBootstrapResourceModelV1 struct {\n\tID                    types.String          `tfsdk:\"id\"`\n\tEndpoint              types.String          `tfsdk:\"endpoint\"`\n\tNode                  types.String          `tfsdk:\"node\"`\n\tClientConfiguration   basetypes.ObjectValue `tfsdk:\"client_configuration\"`\n\tClientConfigurationWO basetypes.ObjectValue `tfsdk:\"client_configuration_wo\"`\n\tTimeouts              timeouts.Value        `tfsdk:\"timeouts\"`\n}\n\n// NewTalosMachineBootstrapResource implements the resource.Resource interface.\nfunc NewTalosMachineBootstrapResource() resource.Resource {\n\treturn &talosMachineBootstrapResource{}\n}\n\nfunc (r *talosMachineBootstrapResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_machine_bootstrap\"\n}\n\nfunc (r *talosMachineBootstrapResource) ValidateConfig(ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse) {\n\tvar config talosMachineBootstrapResourceModelV1\n\n\tdiags := req.Config.Get(ctx, &config)\n\tresp.Diagnostics.Append(diags...)\n\n\tif diags.HasError() {\n\t\treturn\n\t}\n\n\tclientConfigSet := !config.ClientConfiguration.IsNull()\n\tclientConfigWOSet := !config.ClientConfigurationWO.IsNull()\n\n\tif !clientConfigSet && !clientConfigWOSet {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Missing client configuration\",\n\t\t\t\"Exactly one of client_configuration or client_configuration_wo must be set\",\n\t\t)\n\t}\n\n\tif clientConfigSet && clientConfigWOSet {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Conflicting client configuration\",\n\t\t\t\"Only one of client_configuration or client_configuration_wo can be set, not both\",\n\t\t)\n\t}\n}\n\n// getClientConfiguration returns the effective client configuration,\n// preferring the write-only attribute if set.\nfunc getBootstrapClientConfiguration(state *talosMachineBootstrapResourceModelV1) (config basetypes.ObjectValue, diagMsg string) {\n\twoIsNull := state.ClientConfigurationWO.IsNull()\n\twoIsUnknown := state.ClientConfigurationWO.IsUnknown()\n\tregularIsNull := state.ClientConfiguration.IsNull()\n\n\t// Prefer write-only if available and known\n\tif !woIsNull && !woIsUnknown {\n\t\treturn state.ClientConfigurationWO, \"\"\n\t}\n\n\t// If write-only was provided but is still unknown, that's a problem\n\tif !woIsNull && woIsUnknown {\n\t\treturn basetypes.NewObjectNull(map[string]attr.Type{\n\t\t\t\"ca_certificate\":     types.StringType,\n\t\t\t\"client_certificate\": types.StringType,\n\t\t\t\"client_key\":         types.StringType,\n\t\t}), \"client_configuration_wo is still unknown (ephemeral value not yet resolved)\"\n\t}\n\n\t// Fall back to regular client_configuration\n\tif !regularIsNull {\n\t\treturn state.ClientConfiguration, \"\"\n\t}\n\n\t// Both are null\n\treturn basetypes.NewObjectNull(map[string]attr.Type{\n\t\t\"ca_certificate\":     types.StringType,\n\t\t\"client_certificate\": types.StringType,\n\t\t\"client_key\":         types.StringType,\n\t}), \"both client_configuration and client_configuration_wo are null\"\n}\n\nfunc (r *talosMachineBootstrapResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tVersion:     1,\n\t\tDescription: \"The machine bootstrap resource allows you to bootstrap a Talos node.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"This is a unique identifier for the machine \",\n\t\t\t\tPlanModifiers: []planmodifier.String{\n\t\t\t\t\tstringplanmodifier.UseStateForUnknown(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"endpoint\": schema.StringAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The endpoint of the machine to bootstrap\",\n\t\t\t},\n\t\t\t\"node\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The name of the node to bootstrap\",\n\t\t\t},\n\t\t\t\"client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"The client configuration data\",\n\t\t\t},\n\t\t\t\"client_configuration_wo\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tWriteOnly:   true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tWriteOnly:   true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tWriteOnly:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tOptional:    true,\n\t\t\t\tWriteOnly:   true,\n\t\t\t\tDescription: \"The client configuration data (write-only). Use this instead of client_configuration when using ephemeral resources. Requires Terraform 1.11+\",\n\t\t\t},\n\t\t\t\"timeouts\": timeouts.Attributes(ctx, timeouts.Opts{\n\t\t\t\tCreate: true,\n\t\t\t}),\n\t\t},\n\t}\n}\n\nfunc (r *talosMachineBootstrapResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {\n\tvar state talosMachineBootstrapResourceModelV1\n\n\tdiags := req.Plan.Get(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif diags.HasError() {\n\t\treturn\n\t}\n\n\t// CRITICAL: Write-only attributes are NOT in Plan, only in Config!\n\tvar configState talosMachineBootstrapResourceModelV1\n\n\tconfigDiags := req.Config.Get(ctx, &configState)\n\tresp.Diagnostics.Append(configDiags...)\n\n\tif configDiags.HasError() {\n\t\treturn\n\t}\n\n\t// Use write-only client_configuration from Config\n\tif !configState.ClientConfigurationWO.IsNull() {\n\t\tstate.ClientConfigurationWO = configState.ClientConfigurationWO\n\t}\n\n\tclientConfig, configDiag := getBootstrapClientConfiguration(&state)\n\tif configDiag != \"\" {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Client configuration issue\",\n\t\t\tconfigDiag,\n\t\t)\n\n\t\treturn\n\t}\n\n\tca, cert, key, errMsg, ok := getClientConfigurationValues(ctx, clientConfig)\n\tif !ok {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Error extracting client configuration\",\n\t\t\terrMsg,\n\t\t)\n\n\t\treturn\n\t}\n\n\ttalosClientConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\t\"dynamic\",\n\t\tca,\n\t\tcert,\n\t\tkey,\n\t)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Error converting config to talos client config\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\tcreateTimeout, diags := state.Timeouts.Create(ctx, 10*time.Minute)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tctxDeadline, cancel := context.WithTimeout(ctx, createTimeout)\n\tdefer cancel()\n\n\tif err := retry.RetryContext(ctxDeadline, createTimeout, func() *retry.RetryError {\n\t\tif err := talosClientOp(ctx, state.Endpoint.ValueString(), state.Node.ValueString(), talosClientConfig, func(nodeCtx context.Context, c *client.Client) error {\n\t\t\treturn c.Bootstrap(nodeCtx, &machineapi.BootstrapRequest{})\n\t\t}); err != nil {\n\t\t\tif s := status.Code(err); s == codes.InvalidArgument {\n\t\t\t\treturn retry.NonRetryableError(err)\n\t\t\t}\n\n\t\t\treturn retry.RetryableError(err)\n\t\t}\n\n\t\treturn nil\n\t}); err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Error bootstrapping node\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\tstate.ID = basetypes.NewStringValue(\"machine_bootstrap\")\n\n\t// Set state to fully populated data\n\tdiags = resp.State.Set(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n\nfunc (r *talosMachineBootstrapResource) Read(_ context.Context, _ resource.ReadRequest, _ *resource.ReadResponse) {\n}\n\nfunc (r *talosMachineBootstrapResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {\n\tvar state talosMachineBootstrapResourceModelV1\n\n\tdiags := req.Plan.Get(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif diags.HasError() {\n\t\treturn\n\t}\n\n\t// Set state to fully populated data\n\tdiags = resp.State.Set(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n\nfunc (r *talosMachineBootstrapResource) Delete(_ context.Context, _ resource.DeleteRequest, _ *resource.DeleteResponse) {\n}\n\nfunc (r *talosMachineBootstrapResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {\n\t// delete is a no-op\n\tif req.Plan.Raw.IsNull() {\n\t\treturn\n\t}\n\n\tvar configObj types.Object\n\n\tdiags := req.Config.Get(ctx, &configObj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar config talosMachineBootstrapResourceModelV1\n\n\tdiags = configObj.As(ctx, &config, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\t// if either endpoint or node is unknown return early\n\tif config.Endpoint.IsUnknown() || config.Node.IsUnknown() {\n\t\treturn\n\t}\n\n\tvar planObj types.Object\n\n\tdiags = req.Plan.Get(ctx, &planObj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar planState talosMachineBootstrapResourceModelV1\n\n\tdiags = configObj.As(ctx, &planState, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif planState.Endpoint.IsUnknown() || planState.Endpoint.IsNull() {\n\t\tdiags = resp.Plan.SetAttribute(ctx, path.Root(\"endpoint\"), planState.Node.ValueString())\n\t\tresp.Diagnostics.Append(diags...)\n\n\t\tif diags.HasError() {\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (r *talosMachineBootstrapResource) UpgradeState(_ context.Context) map[int64]resource.StateUpgrader {\n\treturn map[int64]resource.StateUpgrader{\n\t\t0: {\n\t\t\tPriorSchema: &schema.Schema{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\t\t\tComputed: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"endpoint\": schema.StringAttribute{\n\t\t\t\t\t\tRequired: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"node\": schema.StringAttribute{\n\t\t\t\t\t\tRequired: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"talos_config\": schema.StringAttribute{\n\t\t\t\t\t\tRequired: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tStateUpgrader: func(ctx context.Context, req resource.UpgradeStateRequest, resp *resource.UpgradeStateResponse) {\n\t\t\t\tvar priorStateData talosMachineBootstrapResourceModelV0\n\n\t\t\t\tdiags := req.State.Get(ctx, &priorStateData)\n\t\t\t\tresp.Diagnostics.Append(diags...)\n\n\t\t\t\tif diags.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\ttimeout, diag := basetypes.NewObjectValue(map[string]attr.Type{\n\t\t\t\t\t\"create\": types.StringType,\n\t\t\t\t}, map[string]attr.Value{\n\t\t\t\t\t\"create\": basetypes.NewStringNull(),\n\t\t\t\t})\n\t\t\t\tresp.Diagnostics.Append(diag...)\n\n\t\t\t\tif resp.Diagnostics.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Create null client configuration with proper type\n\t\t\t\tclientConfig := basetypes.NewObjectNull(map[string]attr.Type{\n\t\t\t\t\t\"ca_certificate\":     types.StringType,\n\t\t\t\t\t\"client_certificate\": types.StringType,\n\t\t\t\t\t\"client_key\":         types.StringType,\n\t\t\t\t})\n\n\t\t\t\tstate := talosMachineBootstrapResourceModelV1{\n\t\t\t\t\tID:                    basetypes.NewStringValue(\"machine_bootstrap\"),\n\t\t\t\t\tEndpoint:              priorStateData.Endpoint,\n\t\t\t\t\tNode:                  priorStateData.Node,\n\t\t\t\t\tClientConfiguration:   clientConfig,\n\t\t\t\t\tClientConfigurationWO: clientConfig,\n\t\t\t\t\tTimeouts: timeouts.Value{\n\t\t\t\t\t\tObject: timeout,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\t// Set state to fully populated data\n\t\t\t\tdiags = resp.State.Set(ctx, &state)\n\t\t\t\tresp.Diagnostics.Append(diags...)\n\n\t\t\t\tif resp.Diagnostics.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (r *talosMachineBootstrapResource) ImportState(ctx context.Context, _ resource.ImportStateRequest, resp *resource.ImportStateResponse) {\n\ttimeout, diag := basetypes.NewObjectValue(map[string]attr.Type{\n\t\t\"create\": types.StringType,\n\t}, map[string]attr.Value{\n\t\t\"create\": basetypes.NewStringNull(),\n\t})\n\tresp.Diagnostics.Append(diag...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\t// Create null client configuration with proper type\n\tclientConfig := basetypes.NewObjectNull(map[string]attr.Type{\n\t\t\"ca_certificate\":     types.StringType,\n\t\t\"client_certificate\": types.StringType,\n\t\t\"client_key\":         types.StringType,\n\t})\n\n\tstate := talosMachineBootstrapResourceModelV1{\n\t\tID:                    basetypes.NewStringValue(\"machine_bootstrap\"),\n\t\tClientConfiguration:   clientConfig,\n\t\tClientConfigurationWO: clientConfig,\n\t\tTimeouts: timeouts.Value{\n\t\t\tObject: timeout,\n\t\t},\n\t}\n\n\t// Set state to fully populated data\n\tdiags := resp.State.Set(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_bootstrap_resource_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/acctest\"\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n)\n\nfunc TestAccTalosMachineBootstrapResource(t *testing.T) {\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tIsUnitTest:               true, // import can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\t// import the resource\n\t\t\t\tConfig:             testAccTalosMachineBootstrapResourceConfigImport(\"10.5.0.2\"),\n\t\t\t\tResourceName:       \"talos_machine_bootstrap.this\",\n\t\t\t\tImportStateId:      \"this\",\n\t\t\t\tImportState:        true,\n\t\t\t\tImportStatePersist: true,\n\t\t\t},\n\t\t\t// verify state is correct after import\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineBootstrapResourceConfigImport(\"10.5.0.2\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_bootstrap.this\", \"id\", \"machine_bootstrap\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_bootstrap.this\", \"node\", \"10.5.0.2\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_bootstrap.this\", \"endpoint\", \"10.5.0.2\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_bootstrap.this\", \"client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_bootstrap.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_bootstrap.this\", \"client_configuration.client_key\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestAccTalosMachineBootstrapResourceUpgrade(t *testing.T) {\n\t// ref: https://github.com/hashicorp/terraform-plugin-testing/pull/118\n\tt.Skip(\"skipping until TF test framework has a way to remove state resource\")\n\n\trName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)\n\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tSteps: []resource.TestStep{\n\t\t\t// create TF config with v0.1.2 of the talos provider\n\t\t\t{\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"talos\": {\n\t\t\t\t\t\tVersionConstraint: \"=0.1.2\",\n\t\t\t\t\t\tSource:            \"siderolabs/talos\",\n\t\t\t\t\t},\n\t\t\t\t\t\"libvirt\": {\n\t\t\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tConfig: testAccTalosMachineBootstrapResourceConfigV0(\"talosv1\", rName),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_client_configuration\", \"this\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_configuration_controlplane\", \"this\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply\", \"id\", \"this\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// now test state migration with the latest version of the provider\n\t\t\t{\n\t\t\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"libvirt\": {\n\t\t\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tConfig: testAccTalosMachineBootstrapResourceConfigV1(\"talos\", rName),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_bootstrap.this\", \"id\", \"machine_bootstrap\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_bootstrap.this\", \"node\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_bootstrap.this\", \"endpoint\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_bootstrap.this\", \"client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_bootstrap.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_bootstrap.this\", \"client_configuration.client_key\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// ensure there is no diff\n\t\t\t{\n\t\t\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"libvirt\": {\n\t\t\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tConfig:   testAccTalosMachineBootstrapResourceConfigV1(\"talos\", rName),\n\t\t\t\tPlanOnly: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosMachineBootstrapResourceConfigV0(providerName, rName string) string {\n\tconfig := dynamicConfig{\n\t\tProvider:        providerName,\n\t\tResourceName:    rName,\n\t\tWithApplyConfig: true,\n\t\tWithBootstrap:   true,\n\t}\n\n\treturn config.render()\n}\n\nfunc testAccTalosMachineBootstrapResourceConfigV1(providerName, rName string) string {\n\tconfig := dynamicConfig{\n\t\tProvider:        providerName,\n\t\tResourceName:    rName,\n\t\tWithApplyConfig: true,\n\t\tWithBootstrap:   true,\n\t}\n\n\treturn config.render()\n}\n\nfunc testAccTalosMachineBootstrapResourceConfigImport(node string) string {\n\treturn fmt.Sprintf(`\nresource \"talos_machine_secrets\" \"this\" {}\n\nresource \"talos_machine_bootstrap\" \"this\" {\n  node                 = \"%s\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n}\n`, node)\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_configuration_apply_resource.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"crypto/sha256\"\n\t\"crypto/tls\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts\"\n\t\"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/attr\"\n\t\"github.com/hashicorp/terraform-plugin-framework/path\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier\"\n\t\"github.com/hashicorp/terraform-plugin-framework/schema/validator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry\"\n\t\"github.com/siderolabs/talos/cmd/talosctl/pkg/talos/action\"\n\tmachineapi \"github.com/siderolabs/talos/pkg/machinery/api/machine\"\n\t\"github.com/siderolabs/talos/pkg/machinery/client\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/configpatcher\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\ntype talosMachineConfigurationApplyResource struct{}\n\nvar (\n\t_ resource.Resource                   = &talosMachineConfigurationApplyResource{}\n\t_ resource.ResourceWithModifyPlan     = &talosMachineConfigurationApplyResource{}\n\t_ resource.ResourceWithUpgradeState   = &talosMachineConfigurationApplyResource{}\n\t_ resource.ResourceWithValidateConfig = &talosMachineConfigurationApplyResource{}\n)\n\nvar onDestroyMarkDownDescription = `Actions to be taken on destroy, if *reset* is not set this is a no-op.\n\n> Note: Any changes to *on_destroy* block has to be applied first by running *terraform apply* first,\nthen a subsequent *terraform destroy* for the changes to take effect due to limitations in Terraform provider framework.\n`\n\ntype talosMachineConfigurationApplyResourceModelV0 struct {\n\tMode                 types.String `tfsdk:\"mode\"`\n\tNode                 types.String `tfsdk:\"node\"`\n\tEndpoint             types.String `tfsdk:\"endpoint\"`\n\tTalosConfig          types.String `tfsdk:\"talos_config\"`\n\tMachineConfiguration types.String `tfsdk:\"machine_configuration\"`\n\tConfigPatches        types.List   `tfsdk:\"config_patches\"`\n}\n\ntype talosMachineConfigurationApplyResourceModelV1 struct { //nolint:govet\n\tID                          types.String          `tfsdk:\"id\"`\n\tApplyMode                   types.String          `tfsdk:\"apply_mode\"`\n\tResolvedApplyMode           types.String          `tfsdk:\"resolved_apply_mode\"`\n\tNode                        types.String          `tfsdk:\"node\"`\n\tEndpoint                    types.String          `tfsdk:\"endpoint\"`\n\tClientConfiguration         basetypes.ObjectValue `tfsdk:\"client_configuration\"`\n\tClientConfigurationWO       basetypes.ObjectValue `tfsdk:\"client_configuration_wo\"`\n\tMachineConfigurationInput   types.String          `tfsdk:\"machine_configuration_input\"`\n\tMachineConfigurationInputWO types.String          `tfsdk:\"machine_configuration_input_wo\"`\n\tOnDestroy                   *onDestroyOptions     `tfsdk:\"on_destroy\"`\n\tMachineConfiguration        types.String          `tfsdk:\"machine_configuration\"`\n\tMachineConfigurationHash    types.String          `tfsdk:\"machine_configuration_hash\"`\n\tConfigPatches               types.List            `tfsdk:\"config_patches\"`\n\tTimeouts                    timeouts.Value        `tfsdk:\"timeouts\"`\n}\n\ntype onDestroyOptions struct {\n\tReset    bool `tfsdk:\"reset\"`\n\tGraceful bool `tfsdk:\"graceful\"`\n\tReboot   bool `tfsdk:\"reboot\"`\n}\n\n// NewTalosMachineConfigurationApplyResource implements the resource.Resource interface.\nfunc NewTalosMachineConfigurationApplyResource() resource.Resource {\n\treturn &talosMachineConfigurationApplyResource{}\n}\n\nfunc (p *talosMachineConfigurationApplyResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_machine_configuration_apply\"\n}\n\nfunc (p *talosMachineConfigurationApplyResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tVersion:     1,\n\t\tDescription: \"The machine configuration apply resource allows to apply machine configuration to a node\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"This is a unique identifier for the machine \",\n\t\t\t\tPlanModifiers: []planmodifier.String{\n\t\t\t\t\tstringplanmodifier.UseStateForUnknown(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"apply_mode\": schema.StringAttribute{\n\t\t\t\tOptional: true,\n\t\t\t\tComputed: true,\n\t\t\t\tDescription: \"The mode of the apply operation. Use 'staged_if_needing_reboot' for automatic reboot prevention: \" +\n\t\t\t\t\t\"performs a dry-run and uses 'staged' mode if reboot is needed, 'auto' otherwise\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tstringvalidator.OneOf(\"auto\", \"reboot\", \"no_reboot\", \"staged\", \"staged_if_needing_reboot\"),\n\t\t\t\t},\n\t\t\t\tDefault: stringdefault.StaticString(\"auto\"),\n\t\t\t},\n\t\t\t\"resolved_apply_mode\": schema.StringAttribute{\n\t\t\t\tComputed: true,\n\t\t\t\tDescription: \"The actual apply mode used. When apply_mode is 'staged_if_needing_reboot', \" +\n\t\t\t\t\t\"shows the resolved mode ('auto' or 'staged') based on dry-run analysis. Equals apply_mode for other modes.\",\n\t\t\t},\n\t\t\t\"node\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The name of the node to bootstrap\",\n\t\t\t},\n\t\t\t\"endpoint\": schema.StringAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The endpoint of the machine to bootstrap\",\n\t\t\t},\n\t\t\t\"client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"The client configuration data\",\n\t\t\t},\n\t\t\t\"client_configuration_wo\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tWriteOnly:   true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tWriteOnly:   true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tWriteOnly:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tOptional:    true,\n\t\t\t\tWriteOnly:   true,\n\t\t\t\tDescription: \"The client configuration data (write-only). Use this instead of client_configuration when using ephemeral resources. Requires Terraform 1.11+\",\n\t\t\t},\n\t\t\t\"machine_configuration_input\": schema.StringAttribute{\n\t\t\t\tDescription: \"The machine configuration to apply\",\n\t\t\t\tOptional:    true,\n\t\t\t\tSensitive:   true,\n\t\t\t},\n\t\t\t\"machine_configuration_input_wo\": schema.StringAttribute{\n\t\t\t\tDescription: \"The machine configuration to apply (write-only). Use this instead of machine_configuration_input when using ephemeral resources. Requires Terraform 1.11+\",\n\t\t\t\tOptional:    true,\n\t\t\t\tWriteOnly:   true,\n\t\t\t},\n\t\t\t\"on_destroy\": schema.SingleNestedAttribute{\n\t\t\t\tDescription:         \"Actions to be taken on destroy, if `reset` is not set this is a no-op.\",\n\t\t\t\tMarkdownDescription: onDestroyMarkDownDescription,\n\t\t\t\tOptional:            true,\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"reset\": schema.BoolAttribute{\n\t\t\t\t\t\tDescription: \"Reset the machine to the initial state (STATE and EPHEMERAL will be wiped). Default false\",\n\t\t\t\t\t\tOptional:    true,\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDefault:     booldefault.StaticBool(false),\n\t\t\t\t\t},\n\t\t\t\t\t\"graceful\": schema.BoolAttribute{\n\t\t\t\t\t\tDescription: \"Graceful indicates whether node should leave etcd before the upgrade, it also enforces etcd checks before leaving. Default true\",\n\t\t\t\t\t\tOptional:    true,\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDefault:     booldefault.StaticBool(true),\n\t\t\t\t\t},\n\t\t\t\t\t\"reboot\": schema.BoolAttribute{\n\t\t\t\t\t\tDescription: \"Reboot indicates whether node should reboot or halt after resetting. Default false\",\n\t\t\t\t\t\tOptional:    true,\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDefault:     booldefault.StaticBool(false),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"machine_configuration\": schema.StringAttribute{\n\t\t\t\tDescription: \"The generated machine configuration after applying patches\",\n\t\t\t\tComputed:    true,\n\t\t\t\tSensitive:   true,\n\t\t\t\tPlanModifiers: []planmodifier.String{\n\t\t\t\t\tstringplanmodifier.UseStateForUnknown(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"machine_configuration_hash\": schema.StringAttribute{\n\t\t\t\tDescription: \"SHA256 hex digest of the rendered machine configuration (input plus patches). \" +\n\t\t\t\t\t\"Persisted in state so that changes to machine_configuration_input_wo — which is write-only \" +\n\t\t\t\t\t\"and itself invisible to state — still surface as plan diffs.\",\n\t\t\t\tComputed: true,\n\t\t\t\tPlanModifiers: []planmodifier.String{\n\t\t\t\t\tstringplanmodifier.UseStateForUnknown(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"config_patches\": schema.ListAttribute{\n\t\t\t\tElementType: types.StringType,\n\t\t\t\tOptional:    true,\n\t\t\t\tDescription: \"The list of config patches to apply\",\n\t\t\t},\n\t\t\t\"timeouts\": timeouts.Attributes(ctx, timeouts.Opts{\n\t\t\t\tCreate: true,\n\t\t\t\tUpdate: true,\n\t\t\t\tDelete: true,\n\t\t\t}),\n\t\t},\n\t}\n}\n\nfunc (p *talosMachineConfigurationApplyResource) ValidateConfig(ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse) {\n\tvar config talosMachineConfigurationApplyResourceModelV1\n\n\tdiags := req.Config.Get(ctx, &config)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tinputSet := !config.MachineConfigurationInput.IsNull()\n\tinputWOSet := !config.MachineConfigurationInputWO.IsNull()\n\n\tif !inputSet && !inputWOSet {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Missing machine configuration input\",\n\t\t\t\"Exactly one of machine_configuration_input or machine_configuration_input_wo must be set\",\n\t\t)\n\t}\n\n\tif inputSet && inputWOSet {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Conflicting machine configuration input\",\n\t\t\t\"Only one of machine_configuration_input or machine_configuration_input_wo can be set, not both\",\n\t\t)\n\t}\n\n\tclientConfigSet := !config.ClientConfiguration.IsNull()\n\tclientConfigWOSet := !config.ClientConfigurationWO.IsNull()\n\n\tif !clientConfigSet && !clientConfigWOSet {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Missing client configuration\",\n\t\t\t\"Exactly one of client_configuration or client_configuration_wo must be set\",\n\t\t)\n\t}\n\n\tif clientConfigSet && clientConfigWOSet {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Conflicting client configuration\",\n\t\t\t\"Only one of client_configuration or client_configuration_wo can be set, not both\",\n\t\t)\n\t}\n}\n\n// getMachineConfigurationInput returns the effective machine configuration input value,\n// preferring the write-only attribute if set.\nfunc getMachineConfigurationInput(state *talosMachineConfigurationApplyResourceModelV1) types.String {\n\tif !state.MachineConfigurationInputWO.IsNull() && !state.MachineConfigurationInputWO.IsUnknown() {\n\t\treturn state.MachineConfigurationInputWO\n\t}\n\n\treturn state.MachineConfigurationInput\n}\n\n// computeMachineConfiguration applies patches to the input configuration and returns the result.\nfunc computeMachineConfiguration(state *talosMachineConfigurationApplyResourceModelV1) (string, error) {\n\tmachineConfigInput := getMachineConfigurationInput(state)\n\tif machineConfigInput.IsNull() {\n\t\treturn \"\", fmt.Errorf(\"machine configuration input is null\")\n\t}\n\n\tconfigPatches, err := configPatchesAsStrings(state.ConfigPatches)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tpatches, err := configpatcher.LoadPatches(configPatches)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error loading config patches: %w\", err)\n\t}\n\n\tcfg, err := configpatcher.Apply(configpatcher.WithBytes([]byte(machineConfigInput.ValueString())), patches)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error applying config patches: %w\", err)\n\t}\n\n\tcfgBytes, err := cfg.Bytes()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error converting config to bytes: %w\", err)\n\t}\n\n\treturn string(cfgBytes), nil\n}\n\n// configPatchesAsStrings extracts a []string from a types.List of strings. It returns\n// an error if the list itself is unknown (caller cannot render in that case) or if any\n// element is unknown; null values are skipped. A null or empty list yields an empty slice.\nfunc configPatchesAsStrings(list types.List) ([]string, error) {\n\tif list.IsUnknown() {\n\t\treturn nil, fmt.Errorf(\"config_patches list is unknown\")\n\t}\n\n\tif list.IsNull() {\n\t\treturn nil, nil\n\t}\n\n\telements := list.Elements()\n\tresult := make([]string, 0, len(elements))\n\n\tfor _, elem := range elements {\n\t\ts, ok := elem.(basetypes.StringValue)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"config_patches element is not a string: %T\", elem)\n\t\t}\n\n\t\tif s.IsUnknown() {\n\t\t\treturn nil, fmt.Errorf(\"config_patches element is unknown\")\n\t\t}\n\n\t\tif s.IsNull() {\n\t\t\tcontinue\n\t\t}\n\n\t\tresult = append(result, s.ValueString())\n\t}\n\n\treturn result, nil\n}\n\n// getClientConfiguration returns the effective client configuration,\n// preferring the write-only attribute if set.\nfunc getClientConfiguration(state *talosMachineConfigurationApplyResourceModelV1) (config basetypes.ObjectValue, diagMsg string) {\n\twoIsNull := state.ClientConfigurationWO.IsNull()\n\twoIsUnknown := state.ClientConfigurationWO.IsUnknown()\n\tregularIsNull := state.ClientConfiguration.IsNull()\n\n\t// Prefer write-only if available and known\n\tif !woIsNull && !woIsUnknown {\n\t\treturn state.ClientConfigurationWO, \"\"\n\t}\n\n\t// If write-only was provided but is still unknown, that's a problem\n\tif !woIsNull && woIsUnknown {\n\t\treturn basetypes.NewObjectNull(map[string]attr.Type{\n\t\t\t\"ca_certificate\":     types.StringType,\n\t\t\t\"client_certificate\": types.StringType,\n\t\t\t\"client_key\":         types.StringType,\n\t\t}), \"client_configuration_wo is still unknown (ephemeral value not yet resolved)\"\n\t}\n\n\t// Fall back to regular client_configuration\n\tif !regularIsNull {\n\t\treturn state.ClientConfiguration, \"\"\n\t}\n\n\t// Both are null\n\treturn basetypes.NewObjectNull(map[string]attr.Type{\n\t\t\"ca_certificate\":     types.StringType,\n\t\t\"client_certificate\": types.StringType,\n\t\t\"client_key\":         types.StringType,\n\t}), \"both client_configuration and client_configuration_wo are null\"\n}\n\n// getClientConfigurationValues extracts the client configuration values from the ObjectValue.\n// Returns empty strings and error message if extraction fails.\n// Handles both properly-typed ObjectValues and plain maps with correct keys (from Vault reconstruction).\nfunc getClientConfigurationValues(ctx context.Context, clientConfig basetypes.ObjectValue) (ca, cert, key, errMsg string, ok bool) {\n\tif clientConfig.IsUnknown() {\n\t\treturn \"\", \"\", \"\", \"client configuration is unknown\", false\n\t}\n\n\tif clientConfig.IsNull() {\n\t\treturn \"\", \"\", \"\", \"client configuration is null\", false\n\t}\n\n\tvar config clientConfiguration\n\tif diags := clientConfig.As(ctx, &config, basetypes.ObjectAsOptions{}); diags.HasError() {\n\t\t// Fallback: Extract values directly from the ObjectValue's attributes\n\t\t// This handles cases where the object is a plain map with correct keys (e.g., reconstructed from Vault)\n\t\t// without full schema metadata attached at runtime\n\t\tattrs := clientConfig.Attributes()\n\n\t\tcaAttr, caOk := attrs[\"ca_certificate\"]\n\t\tcertAttr, certOk := attrs[\"client_certificate\"]\n\t\tkeyAttr, keyOk := attrs[\"client_key\"]\n\n\t\tif !caOk || !certOk || !keyOk {\n\t\t\tmissingKeys := []string{}\n\t\t\tif !caOk {\n\t\t\t\tmissingKeys = append(missingKeys, \"ca_certificate\")\n\t\t\t}\n\n\t\t\tif !certOk {\n\t\t\t\tmissingKeys = append(missingKeys, \"client_certificate\")\n\t\t\t}\n\n\t\t\tif !keyOk {\n\t\t\t\tmissingKeys = append(missingKeys, \"client_key\")\n\t\t\t}\n\n\t\t\treturn \"\", \"\", \"\", fmt.Sprintf(\"missing required keys: %v (available keys: %v)\", missingKeys, getMapKeys(attrs)), false\n\t\t}\n\n\t\t// Type assert to StringValue and extract string\n\t\tcaVal, caIsString := caAttr.(basetypes.StringValue)\n\t\tcertVal, certIsString := certAttr.(basetypes.StringValue)\n\t\tkeyVal, keyIsString := keyAttr.(basetypes.StringValue)\n\n\t\tif !caIsString || !certIsString || !keyIsString {\n\t\t\twrongTypes := []string{}\n\n\t\t\tif !caIsString {\n\t\t\t\twrongTypes = append(wrongTypes, fmt.Sprintf(\"ca_certificate is %T\", caAttr))\n\t\t\t}\n\n\t\t\tif !certIsString {\n\t\t\t\twrongTypes = append(wrongTypes, fmt.Sprintf(\"client_certificate is %T\", certAttr))\n\t\t\t}\n\n\t\t\tif !keyIsString {\n\t\t\t\twrongTypes = append(wrongTypes, fmt.Sprintf(\"client_key is %T\", keyAttr))\n\t\t\t}\n\n\t\t\treturn \"\", \"\", \"\", fmt.Sprintf(\"wrong types for client configuration attributes: %s\", strings.Join(wrongTypes, \", \")), false\n\t\t}\n\n\t\treturn caVal.ValueString(), certVal.ValueString(), keyVal.ValueString(), \"\", true\n\t}\n\n\treturn config.CA.ValueString(), config.Cert.ValueString(), config.Key.ValueString(), \"\", true\n}\n\n// getMapKeys returns the keys of a map for diagnostic purposes.\nfunc getMapKeys(m map[string]attr.Value) []string {\n\tkeys := make([]string, 0, len(m))\n\tfor k := range m {\n\t\tkeys = append(keys, k)\n\t}\n\n\treturn keys\n}\n\nfunc (p *talosMachineConfigurationApplyResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { //nolint:dupl\n\tvar state talosMachineConfigurationApplyResourceModelV1\n\n\tdiags := req.Plan.Get(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif diags.HasError() {\n\t\treturn\n\t}\n\n\t// CRITICAL: Write-only attributes are NOT in Plan, only in Config!\n\t// We need to read write-only attributes from Config\n\tvar configState talosMachineConfigurationApplyResourceModelV1\n\n\tconfigDiags := req.Config.Get(ctx, &configState)\n\tresp.Diagnostics.Append(configDiags...)\n\n\tif configDiags.HasError() {\n\t\treturn\n\t}\n\n\t// Use write-only attributes from Config, everything else from Plan\n\tif !configState.ClientConfigurationWO.IsNull() {\n\t\tstate.ClientConfigurationWO = configState.ClientConfigurationWO\n\t}\n\n\tif !configState.MachineConfigurationInputWO.IsNull() {\n\t\tstate.MachineConfigurationInputWO = configState.MachineConfigurationInputWO\n\t}\n\n\tclientConfig, configDiag := getClientConfiguration(&state)\n\tif configDiag != \"\" {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Client configuration issue\",\n\t\t\tconfigDiag,\n\t\t)\n\n\t\treturn\n\t}\n\n\tca, cert, key, errMsg, ok := getClientConfigurationValues(ctx, clientConfig)\n\tif !ok {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Error reading client configuration\",\n\t\t\terrMsg,\n\t\t)\n\n\t\treturn\n\t}\n\n\ttalosClientConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\t\"dynamic\",\n\t\tca,\n\t\tcert,\n\t\tkey,\n\t)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Error converting config to talos client config\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\tcreateTimeout, diags := state.Timeouts.Create(ctx, 10*time.Minute)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tctxDeadline, cancel := context.WithTimeout(ctx, createTimeout)\n\tdefer cancel()\n\n\teffectiveMode := getEffectiveMode(&state)\n\n\t// Get the machine configuration to apply\n\t// When using write-only inputs, machine_configuration is not stored in state,\n\t// so we need to compute it here from the input and patches\n\tmachineConfigToApply := state.MachineConfiguration.ValueString()\n\tif state.MachineConfiguration.IsNull() && !state.MachineConfigurationInputWO.IsNull() {\n\t\t// Compute configuration from write-only input and patches\n\t\tcomputed, err := computeMachineConfiguration(&state)\n\t\tif err != nil {\n\t\t\tresp.Diagnostics.AddError(\n\t\t\t\t\"Error computing machine configuration\",\n\t\t\t\terr.Error(),\n\t\t\t)\n\n\t\t\treturn\n\t\t}\n\n\t\tmachineConfigToApply = computed\n\t}\n\n\tif err := retry.RetryContext(ctxDeadline, createTimeout, func() *retry.RetryError {\n\t\tif err := talosClientOp(ctx, state.Endpoint.ValueString(), state.Node.ValueString(), talosClientConfig, func(nodeCtx context.Context, c *client.Client) error {\n\t\t\t_, err := c.ApplyConfiguration(nodeCtx, &machineapi.ApplyConfigurationRequest{\n\t\t\t\tMode: machineapi.ApplyConfigurationRequest_Mode(machineapi.ApplyConfigurationRequest_Mode_value[strings.ToUpper(effectiveMode)]),\n\t\t\t\tData: []byte(machineConfigToApply),\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\treturn nil\n\t\t}); err != nil {\n\t\t\tif s := status.Code(err); s == codes.InvalidArgument {\n\t\t\t\treturn retry.NonRetryableError(err)\n\t\t\t}\n\n\t\t\treturn retry.RetryableError(err)\n\t\t}\n\n\t\treturn nil\n\t}); err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Error applying configuration\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\tstate.ID = basetypes.NewStringValue(\"machine_configuration_apply\")\n\n\t// Set state to fully populated data\n\tdiags = resp.State.Set(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n\nfunc (p *talosMachineConfigurationApplyResource) Read(_ context.Context, _ resource.ReadRequest, _ *resource.ReadResponse) {\n}\n\nfunc (p *talosMachineConfigurationApplyResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { //nolint:dupl\n\tvar state talosMachineConfigurationApplyResourceModelV1\n\n\tdiags := req.Plan.Get(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif diags.HasError() {\n\t\treturn\n\t}\n\n\t// CRITICAL: Write-only attributes are NOT in Plan, only in Config!\n\tvar configState talosMachineConfigurationApplyResourceModelV1\n\n\tconfigDiags := req.Config.Get(ctx, &configState)\n\tresp.Diagnostics.Append(configDiags...)\n\n\tif configDiags.HasError() {\n\t\treturn\n\t}\n\n\t// Use write-only attributes from Config\n\tif !configState.ClientConfigurationWO.IsNull() {\n\t\tstate.ClientConfigurationWO = configState.ClientConfigurationWO\n\t}\n\n\tif !configState.MachineConfigurationInputWO.IsNull() {\n\t\tstate.MachineConfigurationInputWO = configState.MachineConfigurationInputWO\n\t}\n\n\tclientConfig, configDiag := getClientConfiguration(&state)\n\tif configDiag != \"\" {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Client configuration issue\",\n\t\t\tconfigDiag,\n\t\t)\n\n\t\treturn\n\t}\n\n\tca, cert, key, errMsg, ok := getClientConfigurationValues(ctx, clientConfig)\n\tif !ok {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Error reading client configuration\",\n\t\t\terrMsg,\n\t\t)\n\n\t\treturn\n\t}\n\n\ttalosClientConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\t\"dynamic\",\n\t\tca,\n\t\tcert,\n\t\tkey,\n\t)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Error converting config to talos client config\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\tupdateTimeout, diags := state.Timeouts.Update(ctx, 10*time.Minute)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tctxDeadline, cancel := context.WithTimeout(ctx, updateTimeout)\n\tdefer cancel()\n\n\teffectiveMode := getEffectiveMode(&state)\n\n\t// Get the machine configuration to apply\n\t// When using write-only inputs, machine_configuration is not stored in state,\n\t// so we need to compute it here from the input and patches\n\tmachineConfigToApply := state.MachineConfiguration.ValueString()\n\tif state.MachineConfiguration.IsNull() && !state.MachineConfigurationInputWO.IsNull() {\n\t\t// Compute configuration from write-only input and patches\n\t\tcomputed, err := computeMachineConfiguration(&state)\n\t\tif err != nil {\n\t\t\tresp.Diagnostics.AddError(\n\t\t\t\t\"Error computing machine configuration\",\n\t\t\t\terr.Error(),\n\t\t\t)\n\n\t\t\treturn\n\t\t}\n\n\t\tmachineConfigToApply = computed\n\t}\n\n\tif err := retry.RetryContext(ctxDeadline, updateTimeout, func() *retry.RetryError {\n\t\tif err := talosClientOp(ctx, state.Endpoint.ValueString(), state.Node.ValueString(), talosClientConfig, func(nodeCtx context.Context, c *client.Client) error {\n\t\t\t_, err := c.ApplyConfiguration(nodeCtx, &machineapi.ApplyConfigurationRequest{\n\t\t\t\tMode: machineapi.ApplyConfigurationRequest_Mode(machineapi.ApplyConfigurationRequest_Mode_value[strings.ToUpper(effectiveMode)]),\n\t\t\t\tData: []byte(machineConfigToApply),\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\treturn nil\n\t\t}); err != nil {\n\t\t\tif s := status.Code(err); s == codes.InvalidArgument {\n\t\t\t\treturn retry.NonRetryableError(err)\n\t\t\t}\n\n\t\t\treturn retry.RetryableError(err)\n\t\t}\n\n\t\treturn nil\n\t}); err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"Error applying configuration\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\tstate.ID = basetypes.NewStringValue(\"machine_configuration_apply\")\n\n\t// Set state to fully populated data\n\tdiags = resp.State.Set(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n\nfunc getEffectiveMode(state *talosMachineConfigurationApplyResourceModelV1) string {\n\teffectiveMode := state.ResolvedApplyMode.ValueString()\n\tif effectiveMode == \"\" || state.ResolvedApplyMode.IsNull() {\n\t\teffectiveMode = state.ApplyMode.ValueString()\n\t}\n\n\treturn effectiveMode\n}\n\nfunc (p *talosMachineConfigurationApplyResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {\n\tvar state talosMachineConfigurationApplyResourceModelV1\n\n\tdiags := req.State.Get(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif diags.HasError() {\n\t\treturn\n\t}\n\n\tif state.OnDestroy != nil && state.OnDestroy.Reset {\n\t\t// NOTE: During Delete, write-only attributes are not available (not in state)\n\t\t// If using client_configuration_wo, the reset on destroy won't work\n\t\t// Users must use client_configuration (non-write-only) if they need on_destroy.reset\n\t\tclientConfig, configDiag := getClientConfiguration(&state)\n\t\tif configDiag != \"\" {\n\t\t\tresp.Diagnostics.AddError(\n\t\t\t\t\"Client configuration issue during destroy\",\n\t\t\t\tfmt.Sprintf(\"%s\\n\\nNote: If you're using client_configuration_wo (write-only), \"+\n\t\t\t\t\t\"it's not available during destroy. Use client_configuration instead if you need on_destroy.reset functionality.\",\n\t\t\t\t\tconfigDiag),\n\t\t\t)\n\n\t\t\treturn\n\t\t}\n\n\t\tca, cert, key, errMsg, ok := getClientConfigurationValues(ctx, clientConfig)\n\t\tif !ok {\n\t\t\tresp.Diagnostics.AddError(\n\t\t\t\t\"Error reading client configuration\",\n\t\t\t\terrMsg,\n\t\t\t)\n\n\t\t\treturn\n\t\t}\n\n\t\ttalosClientConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\t\t\"dynamic\",\n\t\t\tca,\n\t\t\tcert,\n\t\t\tkey,\n\t\t)\n\t\tif err != nil {\n\t\t\tresp.Diagnostics.AddError(\n\t\t\t\t\"Error converting config to talos client config\",\n\t\t\t\terr.Error(),\n\t\t\t)\n\n\t\t\treturn\n\t\t}\n\n\t\tdeleteTimeout, diags := state.Timeouts.Delete(ctx, 10*time.Minute)\n\t\tresp.Diagnostics.Append(diags...)\n\n\t\tif resp.Diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\n\t\tresetRequest := &machineapi.ResetRequest{\n\t\t\tGraceful: state.OnDestroy.Graceful,\n\t\t\tReboot:   state.OnDestroy.Reboot,\n\t\t\tSystemPartitionsToWipe: []*machineapi.ResetPartitionSpec{\n\t\t\t\t{\n\t\t\t\t\tLabel: \"STATE\",\n\t\t\t\t\tWipe:  true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tLabel: \"EPHEMERAL\",\n\t\t\t\t\tWipe:  true,\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\n\t\tactionFn := func(ctx context.Context, c *client.Client) (string, error) {\n\t\t\treturn resetGetActorID(ctx, c, resetRequest)\n\t\t}\n\n\t\tvar postCheckFn func(context.Context, *client.Client, string) error\n\n\t\tif state.OnDestroy.Reboot {\n\t\t\tpostCheckFn = func(ctx context.Context, c *client.Client, preActionBootID string) error {\n\t\t\t\tinsecureClient, err := client.New(\n\t\t\t\t\tctx,\n\t\t\t\t\tclient.WithTLSConfig(&tls.Config{\n\t\t\t\t\t\tInsecureSkipVerify: true,\n\t\t\t\t\t}),\n\t\t\t\t\tclient.WithEndpoints(state.Endpoint.ValueString()),\n\t\t\t\t)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\t_, err = insecureClient.Disks(client.WithNode(ctx, state.Node.ValueString()))\n\n\t\t\t\t// if we can get into maintenance mode, reset has succeeded\n\t\t\t\tif err == nil {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\t// try to get the boot ID in the normal mode to see if the node has rebooted\n\t\t\t\treturn action.BootIDChangedPostCheckFn(ctx, c, preActionBootID)\n\t\t\t}\n\t\t}\n\n\t\tif err := talosClientOp(ctx, state.Endpoint.ValueString(), state.Node.ValueString(), talosClientConfig, func(_ context.Context, c *client.Client) error {\n\t\t\texecutor := newClientExecutor(c, []string{state.Node.ValueString()})\n\n\t\t\treturn action.NewTracker(\n\t\t\t\texecutor,\n\t\t\t\taction.StopAllServicesEventFn,\n\t\t\t\tactionFn,\n\t\t\t\taction.WithPostCheck(postCheckFn),\n\t\t\t\taction.WithDebug(false),\n\t\t\t\taction.WithTimeout(deleteTimeout),\n\t\t\t).Run()\n\t\t}); err != nil {\n\t\t\tresp.Diagnostics.AddError(\"Error resetting machine\", err.Error())\n\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc setResolvedApplyMode(ctx context.Context, resp *resource.ModifyPlanResponse, mode string) {\n\tdiags := resp.Plan.SetAttribute(ctx, path.Root(\"resolved_apply_mode\"), mode)\n\tresp.Diagnostics.Append(diags...)\n}\n\nfunc dryRunNeedsReboot(cfgBytes []byte, needsReboot *bool) func(context.Context, *client.Client) error {\n\treturn func(nodeCtx context.Context, c *client.Client) error {\n\t\tapplyResp, err := c.ApplyConfiguration(nodeCtx, &machineapi.ApplyConfigurationRequest{\n\t\t\tMode:   machineapi.ApplyConfigurationRequest_AUTO,\n\t\t\tData:   cfgBytes,\n\t\t\tDryRun: true,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif len(applyResp.Messages) > 0 {\n\t\t\t*needsReboot = (applyResp.Messages[0].Mode == machineapi.ApplyConfigurationRequest_REBOOT)\n\t\t}\n\n\t\treturn nil\n\t}\n}\n\nfunc (p *talosMachineConfigurationApplyResource) handleRebootPrevention(\n\tctx context.Context,\n\treq resource.ModifyPlanRequest,\n\tresp *resource.ModifyPlanResponse,\n\tplanState *talosMachineConfigurationApplyResourceModelV1,\n\tcfgBytes []byte,\n) {\n\tapplyMode := strings.ToLower(planState.ApplyMode.ValueString())\n\tif applyMode == \"\" || planState.ApplyMode.IsNull() || planState.ApplyMode.IsUnknown() {\n\t\tapplyMode = \"auto\"\n\t}\n\n\tif applyMode != \"staged_if_needing_reboot\" {\n\t\tsetResolvedApplyMode(ctx, resp, applyMode)\n\n\t\treturn\n\t}\n\n\t// Cannot perform dry-run if node address is unknown (computed from another resource)\n\tif planState.Node.IsUnknown() {\n\t\tsetResolvedApplyMode(ctx, resp, \"auto\")\n\n\t\treturn\n\t}\n\n\t// For updates: avoid unnecessary dry-run if configuration hasn't changed\n\tif !req.State.Raw.IsNull() {\n\t\tvar currentState talosMachineConfigurationApplyResourceModelV1\n\n\t\tdiags := req.State.Get(ctx, &currentState)\n\t\tif diags.HasError() {\n\t\t\treturn\n\t\t}\n\n\t\tif currentState.MachineConfiguration.Equal(types.StringValue(string(cfgBytes))) {\n\t\t\tif !currentState.ResolvedApplyMode.IsNull() && currentState.ResolvedApplyMode.ValueString() != \"\" {\n\t\t\t\tsetResolvedApplyMode(ctx, resp, currentState.ResolvedApplyMode.ValueString())\n\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tendpoint := planState.Endpoint.ValueString()\n\tif endpoint == \"\" || planState.Endpoint.IsNull() || planState.Endpoint.IsUnknown() {\n\t\tendpoint = planState.Node.ValueString()\n\t}\n\n\t// Cannot perform dry-run if client configuration is unknown (from ephemeral resource)\n\tclientConfig, configDiag := getClientConfiguration(planState)\n\tif configDiag != \"\" {\n\t\t// If configuration is not available (unknown/null), fall back to auto mode\n\t\tsetResolvedApplyMode(ctx, resp, \"auto\")\n\n\t\treturn\n\t}\n\n\tca, cert, key, _, ok := getClientConfigurationValues(ctx, clientConfig)\n\tif !ok {\n\t\tsetResolvedApplyMode(ctx, resp, \"auto\")\n\n\t\treturn\n\t}\n\n\ttalosClientConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\t\"dynamic\",\n\t\tca,\n\t\tcert,\n\t\tkey,\n\t)\n\tif err != nil {\n\t\tresp.Diagnostics.AddWarning(\n\t\t\t\"Cannot check reboot requirement\",\n\t\t\tfmt.Sprintf(\"Node %s: %v. Using 'auto' mode (may reboot).\", planState.Node.ValueString(), err),\n\t\t)\n\t\tsetResolvedApplyMode(ctx, resp, \"auto\")\n\n\t\treturn\n\t}\n\n\tvar needsReboot bool\n\n\terr = talosClientOp(ctx, endpoint, planState.Node.ValueString(), talosClientConfig,\n\t\tdryRunNeedsReboot(cfgBytes, &needsReboot),\n\t)\n\tif err != nil {\n\t\tresp.Diagnostics.AddWarning(\n\t\t\t\"Cannot check reboot requirement\",\n\t\t\tfmt.Sprintf(\"Node %s: %v. Using 'auto' mode (may reboot).\", planState.Node.ValueString(), err),\n\t\t)\n\t\tsetResolvedApplyMode(ctx, resp, \"auto\")\n\n\t\treturn\n\t}\n\n\tif needsReboot {\n\t\tsetResolvedApplyMode(ctx, resp, \"staged\")\n\t\tresp.Diagnostics.AddWarning(\n\t\t\t\"Reboot prevented - using staged mode\",\n\t\t\tfmt.Sprintf(\"Node %s: Configuration requires reboot. Using 'staged' mode. Manually reboot with: talosctl reboot --nodes %s\",\n\t\t\t\tplanState.Node.ValueString(), planState.Node.ValueString()),\n\t\t)\n\t} else {\n\t\tsetResolvedApplyMode(ctx, resp, \"auto\")\n\t}\n}\n\nfunc (p *talosMachineConfigurationApplyResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { //nolint:gocyclo,cyclop\n\t// delete is a no-op\n\tif req.Plan.Raw.IsNull() {\n\t\treturn\n\t}\n\n\tvar configObj types.Object\n\n\tdiags := req.Config.Get(ctx, &configObj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar config talosMachineConfigurationApplyResourceModelV1\n\n\tdiags = configObj.As(ctx, &config, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\t// if either endpoint or node is unknown return early\n\tif config.Endpoint.IsUnknown() || config.Node.IsUnknown() || config.MachineConfiguration.IsUnknown() {\n\t\treturn\n\t}\n\n\tvar planObj types.Object\n\n\tdiags = req.Plan.Get(ctx, &planObj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar planState talosMachineConfigurationApplyResourceModelV1\n\n\tdiags = configObj.As(ctx, &planState, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif planState.Endpoint.IsUnknown() || planState.Endpoint.IsNull() {\n\t\tdiags = resp.Plan.SetAttribute(ctx, path.Root(\"endpoint\"), planState.Node.ValueString())\n\t\tresp.Diagnostics.Append(diags...)\n\n\t\tif diags.HasError() {\n\t\t\treturn\n\t\t}\n\t}\n\n\tmachineConfigInput := getMachineConfigurationInput(&planState)\n\n\t// Only compute machine_configuration if inputs are available\n\t// If inputs are unknown (e.g., ephemeral values not yet resolved), the UseStateForUnknown\n\t// plan modifier will preserve the prior state value to prevent drift\n\tif !machineConfigInput.IsUnknown() && !machineConfigInput.IsNull() {\n\t\t// If the whole config_patches list is unknown (e.g. `[for x in <unknown> : ...]`)\n\t\t// or any element is unknown, we can't render — return so UseStateForUnknown wins.\n\t\tif planState.ConfigPatches.IsUnknown() {\n\t\t\treturn\n\t\t}\n\n\t\tconfigPatches, err := configPatchesAsStrings(planState.ConfigPatches)\n\t\tif err != nil {\n\t\t\t// err is only returned when an element is Unknown — bail out like before.\n\t\t\treturn\n\t\t}\n\n\t\tpatches, err := configpatcher.LoadPatches(configPatches)\n\t\tif err != nil {\n\t\t\tresp.Diagnostics.AddError(\n\t\t\t\t\"Error loading config patches\",\n\t\t\t\terr.Error(),\n\t\t\t)\n\n\t\t\treturn\n\t\t}\n\n\t\tcfg, err := configpatcher.Apply(configpatcher.WithBytes([]byte(machineConfigInput.ValueString())), patches)\n\t\tif err != nil {\n\t\t\tresp.Diagnostics.AddError(\n\t\t\t\t\"Error applying config patches\",\n\t\t\t\terr.Error(),\n\t\t\t)\n\n\t\t\treturn\n\t\t}\n\n\t\tcfgBytes, err := cfg.Bytes()\n\t\tif err != nil {\n\t\t\tresp.Diagnostics.AddError(\n\t\t\t\t\"Error converting config to bytes\",\n\t\t\t\terr.Error(),\n\t\t\t)\n\n\t\t\treturn\n\t\t}\n\n\t\tp.setPlanMachineConfiguration(ctx, resp, &planState, cfgBytes)\n\n\t\tif resp.Diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\n\t\tp.handleRebootPrevention(ctx, req, resp, &planState, cfgBytes)\n\t}\n}\n\n// setPlanMachineConfiguration sets the machine_configuration attribute in the plan.\n// When write-only inputs are used, it sets the value to null to avoid storing secrets in state.\n// It also always sets machine_configuration_hash — a SHA256 fingerprint of the rendered\n// config — so that changes to write-only inputs (invisible to state) surface as plan diffs.\nfunc (p *talosMachineConfigurationApplyResource) setPlanMachineConfiguration(\n\tctx context.Context,\n\tresp *resource.ModifyPlanResponse,\n\tplanState *talosMachineConfigurationApplyResourceModelV1,\n\tcfgBytes []byte,\n) {\n\tsum := sha256.Sum256(cfgBytes)\n\tresp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, path.Root(\"machine_configuration_hash\"), hex.EncodeToString(sum[:]))...)\n\n\t// When using write-only inputs (_wo variants), don't populate the computed\n\t// machine_configuration to prevent secrets from being stored in state.\n\tif !planState.MachineConfigurationInputWO.IsNull() {\n\t\tresp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, path.Root(\"machine_configuration\"), types.StringNull())...)\n\n\t\treturn\n\t}\n\n\tresp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, path.Root(\"machine_configuration\"), string(cfgBytes))...)\n}\n\nfunc (p *talosMachineConfigurationApplyResource) UpgradeState(_ context.Context) map[int64]resource.StateUpgrader {\n\treturn map[int64]resource.StateUpgrader{\n\t\t0: {\n\t\t\tPriorSchema: &schema.Schema{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"mode\": schema.StringAttribute{\n\t\t\t\t\t\tOptional: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"endpoint\": schema.StringAttribute{\n\t\t\t\t\t\tRequired: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"node\": schema.StringAttribute{\n\t\t\t\t\t\tRequired: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"talos_config\": schema.StringAttribute{\n\t\t\t\t\t\tRequired: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"machine_configuration\": schema.StringAttribute{\n\t\t\t\t\t\tRequired: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"config_patches\": schema.ListAttribute{\n\t\t\t\t\t\tOptional:    true,\n\t\t\t\t\t\tElementType: types.StringType,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tStateUpgrader: func(ctx context.Context, req resource.UpgradeStateRequest, resp *resource.UpgradeStateResponse) {\n\t\t\t\tvar priorStateData talosMachineConfigurationApplyResourceModelV0\n\n\t\t\t\tdiags := req.State.Get(ctx, &priorStateData)\n\t\t\t\tresp.Diagnostics.Append(diags...)\n\n\t\t\t\tif diags.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tvar patches []string\n\n\t\t\t\tdiags = append(diags, priorStateData.ConfigPatches.ElementsAs(ctx, &patches, true)...)\n\t\t\t\tresp.Diagnostics.Append(diags...)\n\n\t\t\t\tif diags.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconfigPatchesElems := make([]attr.Value, len(patches))\n\t\t\t\tfor i, patch := range patches {\n\t\t\t\t\tconfigPatchesElems[i] = basetypes.NewStringValue(patch)\n\t\t\t\t}\n\n\t\t\t\tconfigPatches, listDiags := basetypes.NewListValue(types.StringType, configPatchesElems)\n\t\t\t\tresp.Diagnostics.Append(listDiags...)\n\n\t\t\t\tif resp.Diagnostics.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\ttimeout, diag := basetypes.NewObjectValue(map[string]attr.Type{\n\t\t\t\t\t\"create\": types.StringType,\n\t\t\t\t\t\"update\": types.StringType,\n\t\t\t\t}, map[string]attr.Value{\n\t\t\t\t\t\"create\": basetypes.NewStringNull(),\n\t\t\t\t\t\"update\": basetypes.NewStringNull(),\n\t\t\t\t})\n\t\t\t\tresp.Diagnostics.Append(diag...)\n\n\t\t\t\tif resp.Diagnostics.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tstate := talosMachineConfigurationApplyResourceModelV1{\n\t\t\t\t\tID:                        basetypes.NewStringValue(\"machine_configuration_apply\"),\n\t\t\t\t\tApplyMode:                 priorStateData.Mode,\n\t\t\t\t\tNode:                      priorStateData.Node,\n\t\t\t\t\tEndpoint:                  priorStateData.Endpoint,\n\t\t\t\t\tMachineConfigurationInput: priorStateData.MachineConfiguration,\n\t\t\t\t\tConfigPatches:             configPatches,\n\t\t\t\t\tTimeouts: timeouts.Value{\n\t\t\t\t\t\tObject: timeout,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\t// Set state to fully populated data\n\t\t\t\tdiags = resp.State.Set(ctx, &state)\n\t\t\t\tresp.Diagnostics.Append(diags...)\n\n\t\t\t\tif resp.Diagnostics.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc resetGetActorID(ctx context.Context, c *client.Client, req *machineapi.ResetRequest) (string, error) {\n\tresp, err := c.ResetGenericWithResponse(ctx, req)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif len(resp.GetMessages()) == 0 {\n\t\treturn \"\", errors.New(\"no messages returned from action run\")\n\t}\n\n\treturn resp.GetMessages()[0].GetActorId(), nil\n}\n\ntype clientExecutor struct {\n\tc     *client.Client\n\tnodes []string\n}\n\nfunc newClientExecutor(c *client.Client, nodes []string) *clientExecutor {\n\treturn &clientExecutor{\n\t\tc:     c,\n\t\tnodes: nodes,\n\t}\n}\n\nfunc (c *clientExecutor) WithClient(action func(context.Context, *client.Client) error, _ ...grpc.DialOption) error {\n\tctx := client.WithNodes(context.Background(), c.nodes...)\n\n\treturn action(ctx, c.c)\n}\n\nfunc (c *clientExecutor) NodeList() []string {\n\treturn c.nodes\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_configuration_apply_resource_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/acctest\"\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n\t\"github.com/hashicorp/terraform-plugin-testing/terraform\"\n\t\"github.com/hashicorp/terraform-plugin-testing/tfversion\"\n\t\"github.com/siderolabs/talos/pkg/machinery/gendata\"\n)\n\nfunc TestAccTalosMachineConfigurationApplyResource(t *testing.T) {\n\trName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)\n\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\"libvirt\": {\n\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t},\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineConfigurationApplyResourceConfig(\"talos\", rName),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.this\", \"id\", \"machine_configuration_apply\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.this\", \"apply_mode\", \"auto\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"node\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"endpoint\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"client_configuration.client_key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"machine_configuration_input\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"machine_configuration\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.this\", \"config_patches.#\", \"1\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.this\", \"config_patches.0\", \"\\\"machine\\\":\\n  \\\"install\\\":\\n    \\\"disk\\\": \\\"/dev/vda\\\"\\n\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// ensure there is no diff\n\t\t\t{\n\t\t\t\tConfig:   testAccTalosMachineConfigurationApplyResourceConfig(\"talos\", rName),\n\t\t\t\tPlanOnly: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosMachineConfigurationApplyResourceAutoStaged tests the \"staged_if_needing_reboot\" apply mode.\n//\n// Note on local vs CI environment:\n// During local development, the node IP was sometimes unknown during the plan phase,\n// preventing the dry-run from being performed. However, in CI, the libvirt setup\n// allows the node IP to be known immediately, enabling the dry-run to execute.\n// Since the configuration requires a reboot, the dry-run correctly resolves to\n// \"staged\" mode to prevent uncontrolled reboots.\nfunc TestAccTalosMachineConfigurationApplyResourceAutoStaged(t *testing.T) {\n\trName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)\n\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\"libvirt\": {\n\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t},\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineConfigurationApplyResourceConfigWithAutoStaged(\"talos\", rName),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.staged_if_needing_reboot\", \"id\", \"machine_configuration_apply\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.staged_if_needing_reboot\", \"apply_mode\", \"staged_if_needing_reboot\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.staged_if_needing_reboot\", \"resolved_apply_mode\", \"staged\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\n// logApplyModeState returns a TestCheckFunc that logs the apply_mode and resolved_apply_mode\n// attributes of the staged_if_needing_reboot resource for debugging upgrade tests.\nfunc logApplyModeState(t *testing.T, stepName string) resource.TestCheckFunc {\n\treturn func(s *terraform.State) error {\n\t\trs, ok := s.RootModule().Resources[\"talos_machine_configuration_apply.staged_if_needing_reboot\"]\n\t\tif !ok {\n\t\t\tt.Logf(\"[%s] Resource not found in state\", stepName)\n\n\t\t\treturn nil\n\t\t}\n\n\t\tt.Logf(\"[%s] apply_mode = %q\", stepName, rs.Primary.Attributes[\"apply_mode\"])\n\n\t\tresolvedApplyMode, exists := rs.Primary.Attributes[\"resolved_apply_mode\"]\n\n\t\tswitch {\n\t\tcase !exists:\n\t\t\tt.Logf(\"[%s] resolved_apply_mode = <DOES NOT EXIST>\", stepName)\n\t\tcase resolvedApplyMode == \"\":\n\t\t\tt.Logf(\"[%s] resolved_apply_mode = <EMPTY STRING>\", stepName)\n\t\tdefault:\n\t\t\tt.Logf(\"[%s] resolved_apply_mode = %q\", stepName, resolvedApplyMode)\n\t\t}\n\n\t\treturn nil\n\t}\n}\n\n// TestAccTalosMachineConfigurationApplyResourceUpgradeWithResolvedApplyModeBug tests the bug in v0.10.1.\n//\n// Bug scenario: v0.10.0 → v0.10.1\n//   - v0.10.0: staged_if_needing_reboot and resolved_apply_mode don't exist.\n//   - v0.10.1: add staged_if_needing_reboot, resolved_apply_mode appears but is EMPTY (this is the bug).\nfunc TestAccTalosMachineConfigurationApplyResourceUpgradeWithResolvedApplyModeBug(t *testing.T) {\n\trName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)\n\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tSteps: []resource.TestStep{\n\t\t\t// Step 1: v0.10.0 - staged_if_needing_reboot doesn't exist, use default apply_mode\n\t\t\t{\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"talos\": {\n\t\t\t\t\t\tVersionConstraint: \"=0.10.0\",\n\t\t\t\t\t\tSource:            \"siderolabs/talos\",\n\t\t\t\t\t},\n\t\t\t\t\t\"libvirt\": {\n\t\t\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tConfig: testAccTalosMachineConfigurationApplyResourceConfigAutoStagedUpgrade(rName, \"auto\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tlogApplyModeState(t, \"v0.10.0 - baseline\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.staged_if_needing_reboot\", \"apply_mode\", \"auto\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// Step 2: v0.10.1 - switch to staged_if_needing_reboot, resolved_apply_mode is EMPTY (bug)\n\t\t\t{\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"talos\": {\n\t\t\t\t\t\tVersionConstraint: \"=0.10.1\",\n\t\t\t\t\t\tSource:            \"siderolabs/talos\",\n\t\t\t\t\t},\n\t\t\t\t\t\"libvirt\": {\n\t\t\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tConfig: testAccTalosMachineConfigurationApplyResourceConfigAutoStagedUpgrade(rName, \"staged_if_needing_reboot\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tlogApplyModeState(t, \"v0.10.1 - BUG: resolved_apply_mode is empty\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.staged_if_needing_reboot\", \"apply_mode\", \"staged_if_needing_reboot\"),\n\t\t\t\t\t// Bug: resolved_apply_mode is empty here because config didn't change\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.staged_if_needing_reboot\", \"resolved_apply_mode\", \"\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosMachineConfigurationApplyResourceUpgradeWithResolvedApplyModeFix tests the fix for empty resolved_apply_mode.\n//\n// Fix scenario: v0.10.0 → current version\n//   - v0.10.0: staged_if_needing_reboot and resolved_apply_mode don't exist.\n//   - Current version: resolved_apply_mode is correctly computed (not empty).\nfunc TestAccTalosMachineConfigurationApplyResourceUpgradeWithResolvedApplyModeFix(t *testing.T) {\n\trName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)\n\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tSteps: []resource.TestStep{\n\t\t\t// Step 1: v0.10.0 - staged_if_needing_reboot doesn't exist, use default apply_mode\n\t\t\t{\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"talos\": {\n\t\t\t\t\t\tVersionConstraint: \"=0.10.0\",\n\t\t\t\t\t\tSource:            \"siderolabs/talos\",\n\t\t\t\t\t},\n\t\t\t\t\t\"libvirt\": {\n\t\t\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tConfig: testAccTalosMachineConfigurationApplyResourceConfigAutoStagedUpgrade(rName, \"auto\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tlogApplyModeState(t, \"v0.10.0 - baseline\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.staged_if_needing_reboot\", \"apply_mode\", \"auto\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// Step 2: Current version - switch to staged_if_needing_reboot, resolved_apply_mode is correctly computed\n\t\t\t{\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"libvirt\": {\n\t\t\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\t\t\tConfig:                   testAccTalosMachineConfigurationApplyResourceConfigAutoStagedUpgrade(rName, \"staged_if_needing_reboot\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tlogApplyModeState(t, \"current version - FIX: resolved_apply_mode is computed\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.staged_if_needing_reboot\", \"apply_mode\", \"staged_if_needing_reboot\"),\n\t\t\t\t\t// Fix: resolved_apply_mode should now be computed (not empty)\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.staged_if_needing_reboot\", \"resolved_apply_mode\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestAccTalosMachineConfigurationApplyResourceUpgrade(t *testing.T) {\n\t// ref: https://github.com/hashicorp/terraform-plugin-testing/pull/118\n\tt.Skip(\"skipping until TF test framework has a way to remove state resource\")\n\n\trName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)\n\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tSteps: []resource.TestStep{\n\t\t\t// create TF config with v0.1.2 of the talos provider\n\t\t\t{\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"talos\": {\n\t\t\t\t\t\tVersionConstraint: \"=0.1.2\",\n\t\t\t\t\t\tSource:            \"siderolabs/talos\",\n\t\t\t\t\t},\n\t\t\t\t\t\"libvirt\": {\n\t\t\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tConfig: testAccTalosMachineConfigurationApplyResourceConfigV0(\"talosv1\", rName),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_client_configuration\", \"this\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_configuration_controlplane\", \"this\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// now test state migration with the latest version of the provider\n\t\t\t{\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"libvirt\": {\n\t\t\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\t\t\tConfig:                   testAccTalosMachineConfigurationApplyResourceConfigV1(\"talos\", rName),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.this\", \"id\", \"machine_configuration_apply\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.this\", \"apply_mode\", \"auto\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"node\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"endpoint\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"client_configuration.client_key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"machine_configuration_input\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"machine_configuration\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.this\", \"config_patches.#\", \"1\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.this\", \"config_patches.0\", \"\\\"machine\\\":\\n  \\\"install\\\":\\n    \\\"disk\\\": \\\"/dev/vda\\\"\\n\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// ensure there is no diff\n\t\t\t{\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"libvirt\": {\n\t\t\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\t\t\tConfig:                   testAccTalosMachineConfigurationApplyResourceConfigV1(\"talos\", rName),\n\t\t\t\tPlanOnly:                 true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosMachineConfigurationApplyResourceConfig(providerName, rName string) string {\n\tconfig := dynamicConfig{\n\t\tProvider:        providerName,\n\t\tResourceName:    rName,\n\t\tWithApplyConfig: true,\n\t\tWithBootstrap:   false,\n\t}\n\n\treturn config.render()\n}\n\nfunc testAccTalosMachineConfigurationApplyResourceConfigV0(providerName, rName string) string {\n\tconfig := dynamicConfig{\n\t\tProvider:        providerName,\n\t\tResourceName:    rName,\n\t\tWithApplyConfig: true,\n\t\tWithBootstrap:   false,\n\t}\n\n\treturn config.render()\n}\n\nfunc testAccTalosMachineConfigurationApplyResourceConfigV1(providerName, rName string) string {\n\tconfig := dynamicConfig{\n\t\tProvider:        providerName,\n\t\tResourceName:    rName,\n\t\tWithApplyConfig: true,\n\t\tWithBootstrap:   false,\n\t}\n\n\treturn config.render()\n}\n\nfunc testAccTalosMachineConfigurationApplyResourceConfigWithAutoStaged(providerName, rName string) string {\n\tconfig := dynamicConfig{\n\t\tProvider:               providerName,\n\t\tResourceName:           rName,\n\t\tWithApplyConfig:        true,\n\t\tWithBootstrap:          true,\n\t\tWithRetrieveKubeConfig: true,\n\t\tWithClusterHealth:      true,\n\t}\n\n\tbaseConfig := config.render()\n\n\treturn baseConfig + `\nresource \"talos_machine_configuration_apply\" \"staged_if_needing_reboot\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = libvirt_domain.cp.network_interface[0].addresses[0]\n  apply_mode                  = \"staged_if_needing_reboot\"\n  config_patches = [\n    yamlencode({\n      machine = {\n        files = [\n          {\n            path        = \"/var/etc/example-config.yaml\"\n            permissions = 420  # 0644 in octal\n            op          = \"create\"\n            content     = \"example: staged_if_needing_reboot test\"\n          }\n        ]\n      }\n    }),\n  ]\n  depends_on = [data.talos_cluster_health.this]\n}\n`\n}\n\n// TestAccTalosMachineConfigurationApplyWithEphemeralClientConfigWO tests write-only attributes\n// with ephemeral resources.\n//\n// This test uses ephemeral talos_machine_secrets and talos_machine_configuration WITHOUT\n// persistence (not recommended for production - see docs/guides/using_ephemeral_resources.md).\n// Secrets regenerate on each Open, so the rendered machine configuration — and therefore\n// machine_configuration_hash — differs between plans. ExpectNonEmptyPlan is true to reflect\n// this documented anti-pattern; production usage should persist secrets in a secret manager,\n// which keeps the hash stable across runs.\n//\n// The test validates:\n//   - Write-only attributes work correctly with ephemeral inputs\n//   - Resource creation succeeds with ephemeral values\n//   - Write-only attributes are not stored in state\n//   - machine_configuration_hash IS populated in state (hash fingerprint, not a secret)\n//   - Hash drift surfaces when non-persisted ephemeral secrets regenerate (correct behavior\n//     that was previously hidden by the write-only invisibility to state)\nfunc TestAccTalosMachineConfigurationApplyWithEphemeralClientConfigWO(t *testing.T) {\n\trName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)\n\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_11_0),\n\t\t},\n\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\"libvirt\": {\n\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t},\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineConfigurationApplyWithEphemeralClientConfigWOConfig(rName),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.this\", \"id\", \"machine_configuration_apply\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_configuration_apply.this\", \"apply_mode\", \"auto\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"node\"),\n\t\t\t\t\t// machine_configuration should NOT be in state when using write-only inputs\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_configuration_apply.this\", \"machine_configuration\"),\n\t\t\t\t\t// machine_configuration_hash IS in state — it's a SHA256 fingerprint, not a secret\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_configuration_apply.this\", \"machine_configuration_hash\"),\n\t\t\t\t\t// client_configuration_wo should not be in state (write-only)\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_configuration_apply.this\", \"client_configuration_wo\"),\n\t\t\t\t\t// machine_configuration_input_wo should not be in state (write-only)\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_configuration_apply.this\", \"machine_configuration_input_wo\"),\n\t\t\t\t\t// client_configuration should not be set (using WO variant)\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_configuration_apply.this\", \"client_configuration\"),\n\t\t\t\t\t// machine_configuration_input should not be set (using WO variant)\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_configuration_apply.this\", \"machine_configuration_input\"),\n\t\t\t\t),\n\t\t\t\t// Drift on non-persisted ephemeral secrets: each Open regenerates secrets,\n\t\t\t\t// which changes the rendered machine configuration, which changes the hash.\n\t\t\t\t// This is the correct behavior for this anti-pattern; persist secrets in\n\t\t\t\t// production and the hash stays stable.\n\t\t\t\tExpectNonEmptyPlan: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosMachineConfigurationApplyResourceConfigAutoStagedUpgrade(rName, applyMode string) string {\n\tconfig := dynamicConfig{\n\t\tProvider:        \"talos\",\n\t\tResourceName:    rName,\n\t\tWithApplyConfig: false,\n\t\tWithBootstrap:   false,\n\t}\n\n\tbaseConfig := config.render()\n\n\treturn baseConfig + `\nresource \"talos_machine_configuration_apply\" \"staged_if_needing_reboot\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = libvirt_domain.cp.network_interface[0].addresses[0]\n  apply_mode                  = \"` + applyMode + `\"\n}\n`\n}\n\nfunc testAccTalosMachineConfigurationApplyWithEphemeralClientConfigWOConfig(rName string) string {\n\tcpuMode := cpuModeHostPassthrough\n\tif os.Getenv(\"CI\") != \"\" {\n\t\tcpuMode = cpuModeHostModel\n\t}\n\n\tisoURL := fmt.Sprintf(\"https://github.com/siderolabs/talos/releases/download/%s/metal-amd64.iso\", gendata.VersionTag)\n\n\treturn fmt.Sprintf(`\n# Generate ephemeral machine secrets (NOT persisted - causes expected drift)\n# In production, these should be persisted in a secret manager as documented\nephemeral \"talos_machine_secrets\" \"this\" {}\n\n# Generate ephemeral machine configuration\nephemeral \"talos_machine_configuration\" \"this\" {\n  cluster_name       = \"test-cluster\"\n  cluster_endpoint   = \"https://${libvirt_domain.cp.network_interface[0].addresses[0]}:6443\"\n  machine_type       = \"controlplane\"\n  machine_secrets    = ephemeral.talos_machine_secrets.this.machine_secrets\n  talos_version      = \"%[3]s\"\n  kubernetes_version = \"1.32.2\"\n\n  config_patches = [\n    yamlencode({\n      machine = {\n        install = {\n          disk = \"/dev/vda\"\n        }\n      }\n    })\n  ]\n}\n\n# Create libvirt VM\nresource \"libvirt_volume\" \"cp\" {\n  name = \"%[1]s\"\n  size = 6442450944\n}\n\nresource \"libvirt_domain\" \"cp\" {\n  name     = \"%[1]s\"\n  firmware = \"/usr/share/OVMF/OVMF_CODE.fd\"\n  nvram {\n    file = \"/var/lib/libvirt/qemu/nvram/%[1]s_VARS.fd\"\n    template = \"/usr/share/OVMF/OVMF_VARS_4M.fd\"\n  }\n\n  lifecycle {\n    ignore_changes = [\n      cpu,\n      nvram,\n      disk[\"url\"],\n\t  firmware,\n    ]\n  }\n\n  cpu {\n    mode = \"%[2]s\"\n  }\n\n  console {\n    type        = \"pty\"\n    target_port = \"0\"\n  }\n\n  graphics {\n    type        = \"vnc\"\n    listen_type = \"address\"\n  }\n\n  disk {\n    url = \"%[4]s\"\n  }\n\n  disk {\n    volume_id = libvirt_volume.cp.id\n  }\n\n  boot_device {\n    dev = [\"cdrom\"]\n  }\n\n  network_interface {\n    network_name   = \"default\"\n    wait_for_lease = true\n  }\n\n  vcpu   = \"2\"\n  memory = \"4096\"\n}\n\n# Apply configuration using write-only ephemeral attributes\n# This tests the actual use case: ephemeral inputs -> write-only attributes -> no secrets in state\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration_wo        = ephemeral.talos_machine_secrets.this.client_configuration\n  machine_configuration_input_wo = ephemeral.talos_machine_configuration.this.machine_configuration\n  node                           = libvirt_domain.cp.network_interface[0].addresses[0]\n  endpoint                       = libvirt_domain.cp.network_interface[0].addresses[0]\n}\n`, rName, cpuMode, gendata.VersionTag, isoURL)\n}\n\n// TestAccTalosMachineConfigurationApplyConfigPatchesUnknownList is a regression test for\n// a model-type bug: config_patches is declared as []types.String in the resource model,\n// which cannot hold a whole-list-unknown value. This surfaces when config_patches is\n// derived from a for-expression over an unknown value (e.g. a data source response body),\n// producing:\n//\n//\tReceived unknown value, however the target type cannot handle unknown values.\n//\tPath: config_patches\n//\tTarget Type: []basetypes.StringValue\n//\tSuggested Type: basetypes.ListValue\n//\n// The test uses terraform_data (a built-in resource) whose output attribute is unknown\n// until apply; feeding it through jsondecode + for produces a whole-list-unknown\n// config_patches during plan, which reproduces the failure without requiring libvirt.\nfunc TestAccTalosMachineConfigurationApplyConfigPatchesUnknownList(t *testing.T) {\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_11_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig:             testAccTalosMachineConfigurationApplyConfigPatchesUnknownListConfig(),\n\t\t\t\tPlanOnly:           true,\n\t\t\t\tExpectNonEmptyPlan: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosMachineConfigurationApplyConfigPatchesUnknownListConfig() string {\n\treturn `\nresource \"terraform_data\" \"source\" {\n  input = \"[\\\"a\\\",\\\"b\\\"]\"\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration = {\n    ca_certificate     = \"fake-ca\"\n    client_certificate = \"fake-cert\"\n    client_key         = \"fake-key\"\n  }\n  machine_configuration_input = \"version: v1alpha1\\nmachine:\\n  type: controlplane\\n\"\n  node                        = \"127.0.0.1\"\n  endpoint                    = \"127.0.0.1\"\n  config_patches = [\n    for item in jsondecode(terraform_data.source.output) : yamlencode({\n      machine = { install = { disk = \"/dev/${item}\" } }\n    })\n  ]\n}\n`\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_configuration_data_source.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/diag\"\n\t\"github.com/hashicorp/terraform-plugin-framework/schema/validator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/siderolabs/crypto/x509\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/configpatcher\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/generate/secrets\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/machine\"\n\t\"github.com/siderolabs/talos/pkg/machinery/constants\"\n\t\"github.com/siderolabs/talos/pkg/machinery/gendata\"\n\t\"golang.org/x/mod/semver\"\n)\n\ntype talosMachineConfigurationDataSourceModelV0 struct {\n\tID                   types.String   `tfsdk:\"id\"`\n\tClusterName          types.String   `tfsdk:\"cluster_name\"`\n\tClusterEndpoint      types.String   `tfsdk:\"cluster_endpoint\"`\n\tMachineType          types.String   `tfsdk:\"machine_type\"`\n\tKubernetesVersion    types.String   `tfsdk:\"kubernetes_version\"`\n\tTalosVersion         types.String   `tfsdk:\"talos_version\"`\n\tMachineSecrets       machineSecrets `tfsdk:\"machine_secrets\"`\n\tMachineConfiguration types.String   `tfsdk:\"machine_configuration\"`\n\tConfigPatches        types.List     `tfsdk:\"config_patches\"`\n\tDocs                 types.Bool     `tfsdk:\"docs\"`\n\tExamples             types.Bool     `tfsdk:\"examples\"`\n}\n\ntype talosMachineConfigurationDataSource struct{}\n\nvar (\n\t_ datasource.DataSource                   = &talosMachineConfigurationDataSource{}\n\t_ datasource.DataSourceWithValidateConfig = &talosMachineConfigurationDataSource{}\n)\n\n// NewTalosMachineConfigurationDataSource implements the datasource.DataSource interface.\nfunc NewTalosMachineConfigurationDataSource() datasource.DataSource {\n\treturn &talosMachineConfigurationDataSource{}\n}\n\nfunc (d *talosMachineConfigurationDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_machine_configuration\"\n}\n\nfunc (d *talosMachineConfigurationDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"Generate a machine configuration for a node type\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tComputed: true,\n\t\t\t},\n\t\t\t\"cluster_name\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The name of the talos kubernetes cluster\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tstringvalidator.LengthAtLeast(1),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"cluster_endpoint\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The endpoint of the talos kubernetes cluster\",\n\t\t\t},\n\t\t\t\"machine_secrets\": machineSecretsSchemaAttribute(),\n\t\t\t\"machine_type\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The type of machine to generate the configuration for\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tstringvalidator.OneOf(\"controlplane\", \"worker\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"config_patches\": schema.ListAttribute{\n\t\t\t\tDescription: \"The list of config patches to apply to the generated configuration\",\n\t\t\t\tOptional:    true,\n\t\t\t\tElementType: types.StringType,\n\t\t\t},\n\t\t\t\"kubernetes_version\": schema.StringAttribute{\n\t\t\t\tDescription: \"The version of kubernetes to use\",\n\t\t\t\tOptional:    true,\n\t\t\t},\n\t\t\t\"talos_version\": schema.StringAttribute{\n\t\t\t\tDescription: \"The Talos version contract used to generate the machine configuration. This does not control the installed Talos version. Use `config_patches` to set `machine.install.image` to the desired value. Example values: `v1.12`, `v1.12.1`, `1.12`, `1.12.1`\", // nolint:lll\n\t\t\t\tOptional:    true,\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\ttalosVersionValid(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"docs\": schema.BoolAttribute{\n\t\t\t\tDescription: \"Whether to generate documentation for the generated configuration. Defaults to false\",\n\t\t\t\tOptional:    true,\n\t\t\t},\n\t\t\t\"examples\": schema.BoolAttribute{\n\t\t\t\tDescription: \"Whether to generate examples for the generated configuration. Defaults to false\",\n\t\t\t\tOptional:    true,\n\t\t\t},\n\t\t\t\"machine_configuration\": schema.StringAttribute{\n\t\t\t\tDescription: \"The generated machine configuration\",\n\t\t\t\tComputed:    true,\n\t\t\t\tSensitive:   true,\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (d *talosMachineConfigurationDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {\n\tvar state talosMachineConfigurationDataSourceModelV0\n\n\tdiags := req.Config.Get(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif !state.KubernetesVersion.IsUnknown() && state.KubernetesVersion.IsNull() {\n\t\tstate.KubernetesVersion = basetypes.NewStringValue(constants.DefaultKubernetesVersion)\n\t}\n\n\tif !state.TalosVersion.IsUnknown() && state.TalosVersion.IsNull() {\n\t\tstate.TalosVersion = basetypes.NewStringValue(semver.MajorMinor(gendata.VersionTag))\n\t}\n\n\tvar machineType machine.Type\n\n\tswitch state.MachineType.ValueString() {\n\tcase \"controlplane\":\n\t\tmachineType = machine.TypeControlPlane\n\tcase \"worker\":\n\t\tmachineType = machine.TypeWorker\n\t}\n\n\tmachineSecrets := &secrets.Bundle{\n\t\tClock: secrets.NewFixedClock(time.Now()),\n\t\tCluster: &secrets.Cluster{\n\t\t\tID:     state.MachineSecrets.Cluster.ID.ValueString(),\n\t\t\tSecret: state.MachineSecrets.Cluster.Secret.ValueString(),\n\t\t},\n\t\tSecrets: &secrets.Secrets{\n\t\t\tBootstrapToken:            state.MachineSecrets.Secrets.BootstrapToken.ValueString(),\n\t\t\tSecretboxEncryptionSecret: state.MachineSecrets.Secrets.SecretboxEncryptionSecret.ValueString(),\n\t\t},\n\t\tTrustdInfo: &secrets.TrustdInfo{\n\t\t\tToken: state.MachineSecrets.TrustdInfo.Token.ValueString(),\n\t\t},\n\t}\n\n\tif !state.MachineSecrets.Secrets.AESCBCEncryptionSecret.IsNull() {\n\t\tmachineSecrets.Secrets.AESCBCEncryptionSecret = state.MachineSecrets.Secrets.AESCBCEncryptionSecret.ValueString()\n\t}\n\n\tmachineSecretsCerts, err := machineSecretsCertsToSecretsBundleCerts(state.MachineSecrets.Certs)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to convert machine secrets certs to secrets bundle certs\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\tmachineSecrets.Certs = machineSecretsCerts\n\n\tvar configPatches []string\n\n\tresp.Diagnostics.Append(state.ConfigPatches.ElementsAs(ctx, &configPatches, true)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tgenOptions := &machineConfigGenerateOptions{\n\t\tmachineType:       machineType,\n\t\tclusterName:       state.ClusterName.ValueString(),\n\t\tclusterEndpoint:   state.ClusterEndpoint.ValueString(),\n\t\tmachineSecrets:    machineSecrets,\n\t\tconfigPatches:     configPatches,\n\t\tkubernetesVersion: state.KubernetesVersion.ValueString(),\n\t\ttalosVersion:      state.TalosVersion.ValueString(),\n\t\tdocsEnabled:       state.Docs.ValueBool(),\n\t\texamplesEnabled:   state.Examples.ValueBool(),\n\t}\n\n\tmachineConfiguration, err := genOptions.generate()\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to generate machine configuration\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\tstate.MachineConfiguration = basetypes.NewStringValue(machineConfiguration)\n\tstate.ID = state.ClusterName\n\n\tdiags = resp.State.Set(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n\nfunc (d *talosMachineConfigurationDataSource) ValidateConfig(ctx context.Context, req datasource.ValidateConfigRequest, resp *datasource.ValidateConfigResponse) {\n\tvar obj types.Object\n\n\tdiags := req.Config.Get(ctx, &obj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar state talosMachineConfigurationDataSourceModelV0\n\n\tdiags = obj.As(ctx, &state, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvalidateMachineConfigurationConfig(ctx, state.ClusterEndpoint, state.ConfigPatches, &resp.Diagnostics)\n}\n\nfunc validateMachineConfigurationConfig(ctx context.Context, clusterEndpoint types.String, configPatches types.List, diagnostics *diag.Diagnostics) {\n\tif !clusterEndpoint.IsUnknown() && !clusterEndpoint.IsNull() {\n\t\tif err := validateClusterEndpoint(clusterEndpoint.ValueString()); err != nil {\n\t\t\tdiagnostics.AddError(\n\t\t\t\t\"cluster_endpoint is invalid\",\n\t\t\t\terr.Error(),\n\t\t\t)\n\t\t}\n\t}\n\n\tvar patches []string\n\n\tloadConfigPatches := true\n\n\tfor _, el := range configPatches.Elements() {\n\t\tif el.IsUnknown() || el.IsNull() {\n\t\t\tloadConfigPatches = false\n\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif loadConfigPatches {\n\t\tdiagnostics.Append(configPatches.ElementsAs(ctx, &patches, true)...)\n\n\t\tif diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\n\t\tif _, err := configpatcher.LoadPatches(patches); err != nil {\n\t\t\tdiagnostics.AddError(\n\t\t\t\t\"config_patches are invalid\",\n\t\t\t\terr.Error(),\n\t\t\t)\n\t\t}\n\t}\n}\n\nfunc machineSecretsSchemaAttribute() schema.SingleNestedAttribute {\n\treturn schema.SingleNestedAttribute{\n\t\tDescription: \"The secrets for the talos cluster\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"cluster\": schema.SingleNestedAttribute{\n\t\t\t\tDescription: \"The cluster secrets\",\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The cluster id\",\n\t\t\t\t\t},\n\t\t\t\t\t\"secret\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The cluster secret\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRequired: true,\n\t\t\t},\n\t\t\t\"secrets\": schema.SingleNestedAttribute{\n\t\t\t\tDescription: \"The secrets for the talos kubernetes cluster\",\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"bootstrap_token\": schema.StringAttribute{\n\t\t\t\t\t\tDescription: \"The bootstrap token for the talos kubernetes cluster\",\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t},\n\t\t\t\t\t\"secretbox_encryption_secret\": schema.StringAttribute{\n\t\t\t\t\t\tDescription: \"The secretbox encryption secret for the talos kubernetes cluster\",\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t},\n\t\t\t\t\t\"aescbc_encryption_secret\": schema.StringAttribute{\n\t\t\t\t\t\tDescription: \"The aescbc encryption secret for the talos kubernetes cluster\",\n\t\t\t\t\t\tOptional:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRequired: true,\n\t\t\t},\n\t\t\t\"trustdinfo\": schema.SingleNestedAttribute{\n\t\t\t\tDescription: \"The trustd info for the talos kubernetes cluster\",\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"token\": schema.StringAttribute{\n\t\t\t\t\t\tDescription: \"The trustd token for the talos kubernetes cluster\",\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRequired: true,\n\t\t\t},\n\t\t\t\"certs\": schema.SingleNestedAttribute{\n\t\t\t\tDescription: \"The certs for the talos kubernetes cluster\",\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"etcd\":           certSchemaInput(),\n\t\t\t\t\t\"k8s\":            certSchemaInput(),\n\t\t\t\t\t\"k8s_aggregator\": certSchemaInput(),\n\t\t\t\t\t\"k8s_serviceaccount\": schema.SingleNestedAttribute{\n\t\t\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\t\t\"key\": schema.StringAttribute{\n\t\t\t\t\t\t\t\tDescription: \"The key for the k8s service account\",\n\t\t\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tRequired: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"os\": certSchemaInput(),\n\t\t\t\t},\n\t\t\t\tRequired: true,\n\t\t\t},\n\t\t},\n\t\tRequired: true,\n\t}\n}\n\nfunc certSchemaInput() schema.SingleNestedAttribute {\n\treturn schema.SingleNestedAttribute{\n\t\tDescription: \"The certificate and key pair\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"cert\": schema.StringAttribute{\n\t\t\t\tDescription: \"certificate data\",\n\t\t\t\tRequired:    true,\n\t\t\t},\n\t\t\t\"key\": schema.StringAttribute{\n\t\t\t\tDescription: \"key data\",\n\t\t\t\tRequired:    true,\n\t\t\t\tSensitive:   true,\n\t\t\t},\n\t\t},\n\t\tRequired: true,\n\t}\n}\n\nfunc machineSecretsCertsToSecretsBundleCerts(machineSecretsCerts machineSecretsCerts) (*secrets.Certs, error) {\n\tetcdCertDataX509, err := certDataToX509PEMEncodedCertificateAndKey(machineSecretsCerts.Etcd.Cert.ValueString(), machineSecretsCerts.Etcd.Key.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tk8sCertDataX509, err := certDataToX509PEMEncodedCertificateAndKey(machineSecretsCerts.K8s.Cert.ValueString(), machineSecretsCerts.K8s.Key.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tk8sAggregatorCertDataX509, err := certDataToX509PEMEncodedCertificateAndKey(machineSecretsCerts.K8sAggregator.Cert.ValueString(), machineSecretsCerts.K8sAggregator.Key.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tk8sServiceAccountCertDataX509, err := certDataToX509PEMEncodedKey(machineSecretsCerts.K8sServiceAccount.Key.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tosCertDataX509, err := certDataToX509PEMEncodedCertificateAndKey(machineSecretsCerts.OS.Cert.ValueString(), machineSecretsCerts.OS.Key.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &secrets.Certs{\n\t\tEtcd:              etcdCertDataX509,\n\t\tK8s:               k8sCertDataX509,\n\t\tK8sAggregator:     k8sAggregatorCertDataX509,\n\t\tK8sServiceAccount: k8sServiceAccountCertDataX509,\n\t\tOS:                osCertDataX509,\n\t}, nil\n}\n\nfunc certDataToX509PEMEncodedCertificateAndKey(cert, key string) (*x509.PEMEncodedCertificateAndKey, error) {\n\tcertBytes, err := base64ToBytes(cert)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tkeyBytes, err := base64ToBytes(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &x509.PEMEncodedCertificateAndKey{\n\t\tKey: keyBytes,\n\t\tCrt: certBytes,\n\t}, nil\n}\n\nfunc certDataToX509PEMEncodedKey(key string) (*x509.PEMEncodedKey, error) {\n\tkeyBytes, err := base64ToBytes(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &x509.PEMEncodedKey{\n\t\tKey: keyBytes,\n\t}, nil\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_configuration_data_source_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strings\"\n\t\"testing\"\n\t\"text/template\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/machine\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1\"\n\t\"github.com/siderolabs/talos/pkg/machinery/constants\"\n\t\"github.com/siderolabs/talos/pkg/machinery/gendata\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"go.yaml.in/yaml/v4\"\n\t\"golang.org/x/mod/semver\"\n\n\t\"github.com/siderolabs/terraform-provider-talos/pkg/talos\"\n)\n\nfunc TestAccTalosMachineConfigurationDataSource(t *testing.T) {\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t// test data source with default values\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineConfigurationDataSourceConfig(\"\", \"example-cluster\", \"controlplane\", \"https://cluster.local:6443\", \"\", false, false, true, true),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"id\", \"example-cluster\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"cluster_name\", \"example-cluster\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"cluster_endpoint\", \"https://cluster.local:6443\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_machine_configuration.this\", \"machine_secrets.%\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"machine_type\", \"controlplane\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_machine_configuration.this\", \"config_patches\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"kubernetes_version\", constants.DefaultKubernetesVersion),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"talos_version\", semver.MajorMinor(gendata.VersionTag)),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"docs\", \"true\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"examples\", \"true\"),\n\t\t\t\t\tresource.TestCheckResourceAttrWith(\"data.talos_machine_configuration.this\", \"machine_configuration\", func(value string) error {\n\t\t\t\t\t\treturn validateGeneratedTalosMachineConfig(\n\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\t\"example-cluster\",\n\t\t\t\t\t\t\t\"https://cluster.local:6443\",\n\t\t\t\t\t\t\t\"/dev/sda\",\n\t\t\t\t\t\t\tconstants.DefaultKubernetesVersion,\n\t\t\t\t\t\t\t\"controlplane\",\n\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\tfunc(t *testing.T, config v1alpha1.Config) error {\n\t\t\t\t\t\t\t\tassert.Empty(t, config.Cluster().AESCBCEncryptionSecret())\n\t\t\t\t\t\t\t\tassert.NotEmpty(t, config.Cluster().SecretboxEncryptionSecret())\n\n\t\t\t\t\t\t\t\treturn nil\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\t// test data source with custom values\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineConfigurationDataSourceConfig(\"\", \"example-cluster-1\", \"controlplane\", \"https://cluster-1.local:6443\", \"v1.28.0\", true, false, false, false),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"id\", \"example-cluster-1\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"cluster_name\", \"example-cluster-1\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"cluster_endpoint\", \"https://cluster-1.local:6443\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_machine_configuration.this\", \"machine_secrets.%\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"machine_type\", \"controlplane\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"config_patches.#\", \"3\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"config_patches.0\", \"\\\"machine\\\":\\n  \\\"install\\\":\\n    \\\"disk\\\": \\\"/dev/sdd\\\"\\n\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"kubernetes_version\", \"v1.28.0\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"talos_version\", semver.MajorMinor(gendata.VersionTag)),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"docs\", \"false\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"examples\", \"false\"),\n\t\t\t\t\tresource.TestCheckResourceAttrWith(\"data.talos_machine_configuration.this\", \"machine_configuration\", func(value string) error {\n\t\t\t\t\t\treturn validateGeneratedTalosMachineConfig(\n\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\t\"example-cluster-1\",\n\t\t\t\t\t\t\t\"https://cluster-1.local:6443\",\n\t\t\t\t\t\t\t\"/dev/sdd\",\n\t\t\t\t\t\t\t\"1.28.0\",\n\t\t\t\t\t\t\t\"controlplane\",\n\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\tfunc(t *testing.T, config v1alpha1.Config) error {\n\t\t\t\t\t\t\t\tassert.Equal(t, map[string]string{\"foo\": \"bar\"}, config.Machine().Sysfs())\n\t\t\t\t\t\t\t\tassert.Equal(t, map[string][]string{\"foo\": {\"bar\"}}, config.Cluster().APIServer().ExtraArgs())\n\t\t\t\t\t\t\t\tassert.Equal(t, \"cp-test\", config.Hostname())\n\t\t\t\t\t\t\t\tassert.Empty(t, config.Cluster().AESCBCEncryptionSecret())\n\t\t\t\t\t\t\t\tassert.NotEmpty(t, config.Cluster().SecretboxEncryptionSecret())\n\n\t\t\t\t\t\t\t\treturn nil\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\t// test data source for a worker node\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineConfigurationDataSourceConfig(\"\", \"example-cluster-2\", \"worker\", \"https://cluster-2.local:6443\", \"\", false, false, true, false),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"id\", \"example-cluster-2\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"cluster_name\", \"example-cluster-2\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"cluster_endpoint\", \"https://cluster-2.local:6443\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_machine_configuration.this\", \"machine_secrets.%\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"machine_type\", \"worker\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_machine_configuration.this\", \"config_patches\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"kubernetes_version\", constants.DefaultKubernetesVersion),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"talos_version\", semver.MajorMinor(gendata.VersionTag)),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"docs\", \"true\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"examples\", \"false\"),\n\t\t\t\t\tresource.TestCheckResourceAttrWith(\"data.talos_machine_configuration.this\", \"machine_configuration\", func(value string) error {\n\t\t\t\t\t\treturn validateGeneratedTalosMachineConfig(\n\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\t\"example-cluster-2\",\n\t\t\t\t\t\t\t\"https://cluster-2.local:6443\",\n\t\t\t\t\t\t\t\"/dev/sda\",\n\t\t\t\t\t\t\tconstants.DefaultKubernetesVersion,\n\t\t\t\t\t\t\t\"worker\",\n\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\tnil,\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\t// test data source for talos v1.2 that has aescbc encryption\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineConfigurationDataSourceConfig(\"v1.2\", \"example-cluster-3\", \"controlplane\", \"https://cluster-3.local:6443\", \"\", false, false, false, true),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"id\", \"example-cluster-3\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"cluster_name\", \"example-cluster-3\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"cluster_endpoint\", \"https://cluster-3.local:6443\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_machine_configuration.this\", \"machine_secrets.%\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"machine_type\", \"controlplane\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"data.talos_machine_configuration.this\", \"config_patches\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"kubernetes_version\", constants.DefaultKubernetesVersion),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"talos_version\", \"v1.2\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"docs\", \"false\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_configuration.this\", \"examples\", \"true\"),\n\t\t\t\t\tresource.TestCheckResourceAttrWith(\"data.talos_machine_configuration.this\", \"machine_configuration\", func(value string) error {\n\t\t\t\t\t\treturn validateGeneratedTalosMachineConfig(\n\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\t\"example-cluster-3\",\n\t\t\t\t\t\t\t\"https://cluster-3.local:6443\",\n\t\t\t\t\t\t\t\"/dev/sda\",\n\t\t\t\t\t\t\tconstants.DefaultKubernetesVersion,\n\t\t\t\t\t\t\t\"controlplane\",\n\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\tfunc(t *testing.T, config v1alpha1.Config) error {\n\t\t\t\t\t\t\t\tassert.NotEmpty(t, config.Cluster().AESCBCEncryptionSecret())\n\t\t\t\t\t\t\t\tassert.Empty(t, config.Cluster().SecretboxEncryptionSecret())\n\n\t\t\t\t\t\t\t\treturn nil\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\t})\n\n\tresource.Test(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t// test validating cluster endpoint\n\t\t\t{\n\t\t\t\tConfig:      testAccTalosMachineConfigurationDataSourceConfig(\"\", \"example-cluster-4\", \"controlplane\", \"cluster.local\", \"\", false, false, true, true),\n\t\t\t\tExpectError: regexp.MustCompile(\"no scheme and port specified for the cluster endpoint URL\\ntry: \\\"https://cluster.local:6443\\\"\"),\n\t\t\t},\n\t\t\t// test validating talos machine config features version\n\t\t\t{\n\t\t\t\tConfig:      testAccTalosMachineConfigurationDataSourceConfig(\"nil\", \"example-cluster-5\", \"controlplane\", \"https://cluster.local\", \"\", false, false, true, true),\n\t\t\t\tExpectError: regexp.MustCompile(\"error parsing version \\\"vnil\\\"\"),\n\t\t\t},\n\t\t\t// test validating machine type\n\t\t\t{\n\t\t\t\tConfig:      testAccTalosMachineConfigurationDataSourceConfig(\"\", \"example-cluster-6\", \"control\", \"https://cluster.local\", \"\", false, false, true, true),\n\t\t\t\tExpectError: regexp.MustCompile(\"Attribute machine_type value must be one of:\"),\n\t\t\t},\n\t\t\t// test validating config patches at plan time\n\t\t\t{\n\t\t\t\tPlanOnly:    true,\n\t\t\t\tConfig:      testAccTalosMachineConfigurationDataSourceConfig(\"v1.3\", \"example-cluster-8\", \"controlplane\", \"https://cluster.local\", \"v1.23.0\", true, true, true, true),\n\t\t\t\tExpectError: regexp.MustCompile(`error decoding document /v1alpha1/ \\(line 1\\): unknown keys found during`),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosMachineConfigurationDataSourceConfig(\n\ttalosConfigVersion,\n\tclusterName,\n\tmachineType,\n\tclusterEndpoint,\n\tkubernetesVersion string,\n\tconfigPatches,\n\tinvalidPatch,\n\tdocsEnabled,\n\texamplesEnabled bool,\n) string {\n\ttype templateConfigModel struct {\n\t\tTalosVersion      string\n\t\tClusterName       string\n\t\tClusterEndpoint   string\n\t\tMachineType       string\n\t\tKubernetesVersion string\n\t\tConfigPatches     bool\n\t\tInvalidPatch      bool\n\t\tDocsEnabled       bool\n\t\tExamplesEnabled   bool\n\t}\n\n\ttemplateConfig := templateConfigModel{\n\t\tTalosVersion:      talosConfigVersion,\n\t\tClusterName:       clusterName,\n\t\tClusterEndpoint:   clusterEndpoint,\n\t\tMachineType:       machineType,\n\t\tConfigPatches:     configPatches,\n\t\tInvalidPatch:      invalidPatch,\n\t\tDocsEnabled:       docsEnabled,\n\t\tExamplesEnabled:   examplesEnabled,\n\t\tKubernetesVersion: kubernetesVersion,\n\t}\n\n\tconfigTemplate := `\nvariable \"talos_version\" {\n  type = string\n  default = \"{{ .TalosVersion }}\"\n}\n\nresource \"talos_machine_secrets\" \"this\" {\n  {{ if .TalosVersion  }}talos_version = var.talos_version{{ end }}\n}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name               = \"{{ .ClusterName }}\"\n  cluster_endpoint           = \"{{ .ClusterEndpoint }}\"\n  machine_type               = \"{{ .MachineType }}\"\n  machine_secrets            = talos_machine_secrets.this.machine_secrets\n  {{ if .TalosVersion  }}talos_version    = var.talos_version{{ end }}\n  {{ if .ConfigPatches  }}config_patches             = [\n    yamlencode({\n      machine = {\n        install = {\n      \t  disk = \"/dev/sdd\"\n    \t}\n      }\n    }),\n    file(\"${path.module}/testdata/patch-strategic.yaml\"),\n\t{{ if .InvalidPatch  }}file(\"${path.module}/testdata/patch-invalid.yaml\"),{{ end }}\n    yamlencode({\n      machine = {\n        network = {\n        hostname = \"cp-test\"\n        }\n      }\n    })\n  ]{{ end }}\n  docs                       = {{ .DocsEnabled }}\n  examples                   = {{ .ExamplesEnabled }}\n  {{ if .KubernetesVersion  }}kubernetes_version         = \"{{ .KubernetesVersion }}\"{{ end }}\n}\n`\n\n\tvar config strings.Builder\n\n\ttemplate.Must(template.New(\"tf_config\").Parse(configTemplate)).Execute(&config, templateConfig) //nolint:errcheck\n\n\treturn config.String()\n}\n\nfunc validateGeneratedTalosMachineConfig(\n\tt *testing.T,\n\tclusterName,\n\tendpoint,\n\tinstallDisk,\n\tk8sVersion,\n\tmachineType,\n\tmc string,\n\tdocs,\n\texamples bool,\n\textraChecks func(t *testing.T, config v1alpha1.Config) error,\n) error {\n\tvar machineConfig v1alpha1.Config\n\n\tif err := yaml.Unmarshal([]byte(mc), &machineConfig); err != nil {\n\t\treturn err\n\t}\n\n\tinstallDiskConfig := machineConfig.Machine().Install().Disk()\n\n\tep, err := url.Parse(endpoint)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tswitch machineType {\n\tcase \"controlplane\":\n\t\tassert.Equal(t, machine.TypeControlPlane, machineConfig.Machine().Type())\n\t\tassert.Equal(t, clusterName, machineConfig.Cluster().Name())\n\tcase \"worker\":\n\t\tassert.Equal(t, machine.TypeWorker, machineConfig.Machine().Type())\n\t}\n\n\tassert.Equal(t, ep, machineConfig.Cluster().Endpoint())\n\tassert.Equal(t, constants.DefaultDNSDomain, machineConfig.Cluster().Network().DNSDomain())\n\tassert.Equal(t, installDisk, installDiskConfig)\n\tassert.Equal(t, talos.GenerateInstallerImage(), machineConfig.Machine().Install().Image())\n\tassert.Equal(t, fmt.Sprintf(\"ghcr.io/siderolabs/kubelet:v%s\", k8sVersion), machineConfig.Machine().Kubelet().Image())\n\tassert.Equal(t, \"v1alpha1\", machineConfig.ConfigVersion)\n\tassert.True(t, machineConfig.Cluster().Discovery().Enabled())\n\n\tif docs {\n\t\tassert.Equal(t, \"Indicates the schema used to decode the contents.\", machineConfig.Doc().Field(0).Description)\n\t} else {\n\t\tassert.NotContains(t, mc, \"Indicates the schema used to decode the contents.\")\n\t}\n\n\tif examples {\n\t\t// verifying there's examples\n\t\tassert.Contains(t, mc, (`\n    #   # Uncomment this to enable SANs.\n    #   - 10.0.0.10\n    #   - 172.16.0.10\n    #   - 192.168.0.10\n`))\n\t} else {\n\t\t// verifying there's no examples\n\t\tassert.NotContains(t, mc, (`\n    #   # Uncomment this to enable SANs.\n    #   - 10.0.0.10\n    #   - 172.16.0.10\n    #   - 192.168.0.10\n`))\n\t}\n\n\tif extraChecks != nil {\n\t\treturn extraChecks(t, machineConfig)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_configuration_ephemeral_resource.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/ephemeral\"\n\t\"github.com/hashicorp/terraform-plugin-framework/ephemeral/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/schema/validator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/generate/secrets\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/machine\"\n\t\"github.com/siderolabs/talos/pkg/machinery/constants\"\n\t\"github.com/siderolabs/talos/pkg/machinery/gendata\"\n\t\"golang.org/x/mod/semver\"\n)\n\nvar (\n\t_ ephemeral.EphemeralResource                   = &talosMachineConfigurationEphemeralResource{}\n\t_ ephemeral.EphemeralResourceWithValidateConfig = &talosMachineConfigurationEphemeralResource{}\n)\n\ntype talosMachineConfigurationEphemeralResource struct{}\n\ntype talosMachineConfigurationEphemeralResourceModel struct {\n\tClusterName          types.String   `tfsdk:\"cluster_name\"`\n\tClusterEndpoint      types.String   `tfsdk:\"cluster_endpoint\"`\n\tMachineType          types.String   `tfsdk:\"machine_type\"`\n\tKubernetesVersion    types.String   `tfsdk:\"kubernetes_version\"`\n\tTalosVersion         types.String   `tfsdk:\"talos_version\"`\n\tMachineSecrets       machineSecrets `tfsdk:\"machine_secrets\"`\n\tMachineConfiguration types.String   `tfsdk:\"machine_configuration\"`\n\tConfigPatches        types.List     `tfsdk:\"config_patches\"`\n\tDocs                 types.Bool     `tfsdk:\"docs\"`\n\tExamples             types.Bool     `tfsdk:\"examples\"`\n}\n\n// NewTalosMachineConfigurationEphemeralResource implements the ephemeral.EphemeralResource interface.\nfunc NewTalosMachineConfigurationEphemeralResource() ephemeral.EphemeralResource {\n\treturn &talosMachineConfigurationEphemeralResource{}\n}\n\nfunc (r *talosMachineConfigurationEphemeralResource) Metadata(_ context.Context, req ephemeral.MetadataRequest, resp *ephemeral.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_machine_configuration\"\n}\n\nfunc (r *talosMachineConfigurationEphemeralResource) Schema(_ context.Context, _ ephemeral.SchemaRequest, resp *ephemeral.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"Generate a machine configuration for a node type. This is an ephemeral resource that does not persist secrets in Terraform state.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"cluster_name\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The name of the talos kubernetes cluster\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tstringvalidator.LengthAtLeast(1),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"cluster_endpoint\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The endpoint of the talos kubernetes cluster\",\n\t\t\t},\n\t\t\t\"machine_secrets\": machineSecretsSchemaAttribute(),\n\t\t\t\"machine_type\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The type of machine to generate the configuration for\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\tstringvalidator.OneOf(\"controlplane\", \"worker\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"config_patches\": schema.ListAttribute{\n\t\t\t\tDescription: \"The list of config patches to apply to the generated configuration\",\n\t\t\t\tOptional:    true,\n\t\t\t\tElementType: types.StringType,\n\t\t\t},\n\t\t\t\"kubernetes_version\": schema.StringAttribute{\n\t\t\t\tDescription: \"The version of kubernetes to use\",\n\t\t\t\tOptional:    true,\n\t\t\t\tComputed:    true,\n\t\t\t},\n\t\t\t\"talos_version\": schema.StringAttribute{\n\t\t\t\tDescription: \"The Talos version contract used to generate the machine configuration. This does not control the installed Talos version. Use `config_patches` to set `machine.install.image` to the desired value. Example values: `v1.12`, `v1.12.1`, `1.12`, `1.12.1`\", // nolint:lll\n\t\t\t\tOptional:    true,\n\t\t\t\tComputed:    true,\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\ttalosVersionValid(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"docs\": schema.BoolAttribute{\n\t\t\t\tDescription: \"Whether to generate documentation for the generated configuration. Defaults to false\",\n\t\t\t\tOptional:    true,\n\t\t\t},\n\t\t\t\"examples\": schema.BoolAttribute{\n\t\t\t\tDescription: \"Whether to generate examples for the generated configuration. Defaults to false\",\n\t\t\t\tOptional:    true,\n\t\t\t},\n\t\t\t\"machine_configuration\": schema.StringAttribute{\n\t\t\t\tDescription: \"The generated machine configuration\",\n\t\t\t\tComputed:    true,\n\t\t\t\tSensitive:   true,\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (r *talosMachineConfigurationEphemeralResource) Open(ctx context.Context, req ephemeral.OpenRequest, resp *ephemeral.OpenResponse) {\n\tvar obj types.Object\n\n\tdiags := req.Config.Get(ctx, &obj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar config talosMachineConfigurationEphemeralResourceModel\n\n\tdiags = obj.As(ctx, &config, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tkubernetesVersion := config.KubernetesVersion.ValueString()\n\tif kubernetesVersion == \"\" {\n\t\tkubernetesVersion = constants.DefaultKubernetesVersion\n\t}\n\n\ttalosVersion := config.TalosVersion.ValueString()\n\tif talosVersion == \"\" {\n\t\ttalosVersion = semver.MajorMinor(gendata.VersionTag)\n\t}\n\n\tvar machineType machine.Type\n\n\tswitch config.MachineType.ValueString() {\n\tcase \"controlplane\":\n\t\tmachineType = machine.TypeControlPlane\n\tcase \"worker\":\n\t\tmachineType = machine.TypeWorker\n\t}\n\n\tmachineSecretsBundle := &secrets.Bundle{\n\t\tClock: secrets.NewFixedClock(time.Now()),\n\t\tCluster: &secrets.Cluster{\n\t\t\tID:     config.MachineSecrets.Cluster.ID.ValueString(),\n\t\t\tSecret: config.MachineSecrets.Cluster.Secret.ValueString(),\n\t\t},\n\t\tSecrets: &secrets.Secrets{\n\t\t\tBootstrapToken:            config.MachineSecrets.Secrets.BootstrapToken.ValueString(),\n\t\t\tSecretboxEncryptionSecret: config.MachineSecrets.Secrets.SecretboxEncryptionSecret.ValueString(),\n\t\t},\n\t\tTrustdInfo: &secrets.TrustdInfo{\n\t\t\tToken: config.MachineSecrets.TrustdInfo.Token.ValueString(),\n\t\t},\n\t}\n\n\tif !config.MachineSecrets.Secrets.AESCBCEncryptionSecret.IsNull() {\n\t\tmachineSecretsBundle.Secrets.AESCBCEncryptionSecret = config.MachineSecrets.Secrets.AESCBCEncryptionSecret.ValueString()\n\t}\n\n\tmachineSecretsCerts, err := machineSecretsCertsToSecretsBundleCerts(config.MachineSecrets.Certs)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to convert machine secrets certs to secrets bundle certs\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\tmachineSecretsBundle.Certs = machineSecretsCerts\n\n\tvar configPatches []string\n\n\tresp.Diagnostics.Append(config.ConfigPatches.ElementsAs(ctx, &configPatches, true)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tgenOptions := &machineConfigGenerateOptions{\n\t\tmachineType:       machineType,\n\t\tclusterName:       config.ClusterName.ValueString(),\n\t\tclusterEndpoint:   config.ClusterEndpoint.ValueString(),\n\t\tmachineSecrets:    machineSecretsBundle,\n\t\tconfigPatches:     configPatches,\n\t\tkubernetesVersion: kubernetesVersion,\n\t\ttalosVersion:      talosVersion,\n\t\tdocsEnabled:       config.Docs.ValueBool(),\n\t\texamplesEnabled:   config.Examples.ValueBool(),\n\t}\n\n\tmachineConfiguration, err := genOptions.generate()\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to generate machine configuration\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\tresult := talosMachineConfigurationEphemeralResourceModel{\n\t\tClusterName:          config.ClusterName,\n\t\tClusterEndpoint:      config.ClusterEndpoint,\n\t\tMachineType:          config.MachineType,\n\t\tKubernetesVersion:    basetypes.NewStringValue(kubernetesVersion),\n\t\tTalosVersion:         basetypes.NewStringValue(talosVersion),\n\t\tMachineSecrets:       config.MachineSecrets,\n\t\tMachineConfiguration: basetypes.NewStringValue(machineConfiguration),\n\t\tConfigPatches:        config.ConfigPatches,\n\t\tDocs:                 config.Docs,\n\t\tExamples:             config.Examples,\n\t}\n\n\tdiags = resp.Result.Set(ctx, &result)\n\tresp.Diagnostics.Append(diags...)\n}\n\nfunc (r *talosMachineConfigurationEphemeralResource) ValidateConfig(ctx context.Context, req ephemeral.ValidateConfigRequest, resp *ephemeral.ValidateConfigResponse) {\n\tvar obj types.Object\n\n\tdiags := req.Config.Get(ctx, &obj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar config talosMachineConfigurationEphemeralResourceModel\n\n\tdiags = obj.As(ctx, &config, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvalidateMachineConfigurationConfig(ctx, config.ClusterEndpoint, config.ConfigPatches, &resp.Diagnostics)\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_configuration_ephemeral_resource_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n\t\"github.com/hashicorp/terraform-plugin-testing/knownvalue\"\n\t\"github.com/hashicorp/terraform-plugin-testing/statecheck\"\n\t\"github.com/hashicorp/terraform-plugin-testing/tfjsonpath\"\n\t\"github.com/hashicorp/terraform-plugin-testing/tfversion\"\n)\n\n// TestAccTalosMachineConfigurationEphemeralResource tests that the ephemeral\n// resource generates machine configuration from machine secrets.\nfunc TestAccTalosMachineConfigurationEphemeralResource(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_machine_configuration\" \"this\" {\n\tcluster_name     = \"test-cluster\"\n\tcluster_endpoint = \"https://10.0.0.1:6443\"\n\tmachine_type     = \"controlplane\"\n\tmachine_secrets  = ephemeral.talos_machine_secrets.this.machine_secrets\n}\n\nprovider \"echo\" {\n\tdata = {\n\t\tmachine_configuration = ephemeral.talos_machine_configuration.this.machine_configuration\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"machine_configuration\"), knownvalue.NotNull()),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosMachineConfigurationEphemeralResourceWorker tests generating\n// a worker machine configuration.\nfunc TestAccTalosMachineConfigurationEphemeralResourceWorker(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nephemeral \"talos_machine_configuration\" \"this\" {\n\tcluster_name     = \"test-cluster\"\n\tcluster_endpoint = \"https://10.0.0.1:6443\"\n\tmachine_type     = \"worker\"\n\tmachine_secrets  = ephemeral.talos_machine_secrets.this.machine_secrets\n}\n\nprovider \"echo\" {\n\tdata = {\n\t\tmachine_configuration = ephemeral.talos_machine_configuration.this.machine_configuration\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"machine_configuration\"), knownvalue.NotNull()),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_disks_data_source.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry\"\n\t\"github.com/siderolabs/talos/pkg/machinery/cel\"\n\t\"github.com/siderolabs/talos/pkg/machinery/cel/celenv\"\n\t\"github.com/siderolabs/talos/pkg/machinery/client\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/types/block/blockhelpers\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\n//go:generate go run internal/gen/diskspec.go block.DiskSpec talos_machine_disks_data_source\n\nfunc (e nodiskFoundError) Error() string {\n\treturn \"no disk matching the filter found\"\n}\n\ntype nodiskFoundError struct{}\n\ntype talosMachineDisksDataSource struct{}\n\ntype talosMachineDisksDataSourceModelV1 struct { //nolint:govet\n\tID                  types.String        `tfsdk:\"id\"`\n\tNode                types.String        `tfsdk:\"node\"`\n\tEndpoint            types.String        `tfsdk:\"endpoint\"`\n\tSelector            types.String        `tfsdk:\"selector\"`\n\tClientConfiguration clientConfiguration `tfsdk:\"client_configuration\"`\n\tDisks               []diskspec          `tfsdk:\"disks\"`\n\tTimeouts            timeouts.Value      `tfsdk:\"timeouts\"`\n}\n\nvar _ datasource.DataSource = &talosMachineDisksDataSource{}\n\n// NewTalosMachineDisksDataSource implements the datasource.DataSource interface.\nfunc NewTalosMachineDisksDataSource() datasource.DataSource {\n\treturn &talosMachineDisksDataSource{}\n}\n\nfunc (d *talosMachineDisksDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_machine_disks\"\n}\n\nfunc (d *talosMachineDisksDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"Generate a machine configuration for a node type\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tDescription: \"The generated ID of this resource\",\n\t\t\t\tComputed:    true,\n\t\t\t},\n\t\t\t\"node\": schema.StringAttribute{\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"controlplane node to retrieve the kubeconfig from\",\n\t\t\t},\n\t\t\t\"endpoint\": schema.StringAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"endpoint to use for the talosclient. If not set, the node value will be used\",\n\t\t\t},\n\t\t\t\"client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tRequired:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tRequired:    true,\n\t\t\t\tDescription: \"The client configuration data\",\n\t\t\t},\n\t\t\t\"selector\": schema.StringAttribute{\n\t\t\t\tOptional: true,\n\t\t\t\tMarkdownDescription: `The CEL expression to filter the disks.\nIf not set, all disks will be returned.\nSee [CEL documentation](https://www.talos.dev/latest/talos-guides/configuration/disk-management/#disk-selector).`,\n\t\t\t},\n\t\t\t\"disks\": schema.ListNestedAttribute{\n\t\t\t\tDescription: \"The disks that match the filters\",\n\t\t\t\tNestedObject: schema.NestedAttributeObject{\n\t\t\t\t\tAttributes: diskspecAttributes,\n\t\t\t\t},\n\t\t\t\tComputed: true,\n\t\t\t},\n\t\t\t\"timeouts\": timeouts.Attributes(ctx, timeouts.Opts{\n\t\t\t\tRead: true,\n\t\t\t}),\n\t\t},\n\t}\n}\n\nfunc (d *talosMachineDisksDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { //nolint:gocognit,gocyclo,cyclop\n\tvar obj types.Object\n\n\tdiags := req.Config.Get(ctx, &obj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar state talosMachineDisksDataSourceModelV1\n\n\tdiags = obj.As(ctx, &state, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\ttalosConfig, err := talosClientTFConfigToTalosClientConfig(\n\t\t\"dynamic\",\n\t\tstate.ClientConfiguration.CA.ValueString(),\n\t\tstate.ClientConfiguration.Cert.ValueString(),\n\t\tstate.ClientConfiguration.Key.ValueString(),\n\t)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to generate talos config\", err.Error())\n\n\t\treturn\n\t}\n\n\tif state.Endpoint.IsNull() {\n\t\tstate.Endpoint = state.Node\n\t}\n\n\treadTimeout, diags := state.Timeouts.Read(ctx, 10*time.Minute)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tctxDeadline, cancel := context.WithTimeout(ctx, readTimeout)\n\tdefer cancel()\n\n\tselector := state.Selector.ValueString()\n\n\tif selector == \"\" {\n\t\t// if there is no selector, we can return all disks\n\t\tselector = \"true\"\n\t}\n\n\texp, err := cel.ParseBooleanExpression(selector, celenv.DiskLocator())\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to parse celenv selector\", err.Error())\n\n\t\treturn\n\t}\n\n\tif err := retry.RetryContext(ctxDeadline, readTimeout, func() *retry.RetryError {\n\t\tif err := talosClientOp(ctx, state.Endpoint.ValueString(), state.Node.ValueString(), talosConfig, func(nodeCtx context.Context, c *client.Client) error {\n\t\t\tdisks, err := blockhelpers.MatchDisks(nodeCtx, c.COSI, &exp)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tfor _, disk := range disks {\n\t\t\t\tstate.Disks = append(state.Disks, diskspecToTFTypes(*disk.TypedSpec()))\n\t\t\t}\n\n\t\t\treturn nil\n\t\t}); err != nil {\n\t\t\tif s := status.Code(err); s == codes.InvalidArgument {\n\t\t\t\treturn retry.NonRetryableError(err)\n\t\t\t}\n\n\t\t\tif errors.Is(err, nodiskFoundError{}) {\n\t\t\t\treturn retry.NonRetryableError(err)\n\t\t\t}\n\n\t\t\treturn retry.RetryableError(err)\n\t\t}\n\n\t\treturn nil\n\t}); err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to get list of disks\", err.Error())\n\n\t\treturn\n\t}\n\n\tstate.ID = basetypes.NewStringValue(\"machine_disks\")\n\n\tdiags = resp.State.Set(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_disks_data_source_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/acctest\"\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n)\n\nfunc TestAccTalosMachineDisksDataSource(t *testing.T) {\n\trName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)\n\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\"libvirt\": {\n\t\t\t\tSource:            \"dmacvicar/libvirt\",\n\t\t\t\tVersionConstraint: \"= 0.8.3\",\n\t\t\t},\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t// test default config\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineDisksDataSourceConfigV0(\"talos\", rName),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_disks.this\", \"id\", \"machine_disks\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_machine_disks.this\", \"node\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_machine_disks.this\", \"endpoint\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_machine_disks.this\", \"client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_machine_disks.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"data.talos_machine_disks.this\", \"client_configuration.client_key\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_disks.this\", \"selector\", \"disk.size > 6u * GB\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_disks.this\", \"disks.#\", \"1\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"data.talos_machine_disks.this\", \"disks.0.dev_path\", \"/dev/vda\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosMachineDisksDataSourceConfigV0(providerName, rName string) string {\n\tconfig := dynamicConfig{\n\t\tProvider:        providerName,\n\t\tResourceName:    rName,\n\t\tWithApplyConfig: false,\n\t\tWithBootstrap:   false,\n\t}\n\n\treturn config.render()\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_disks_data_source_types.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n// Code generated by \"diskspec.go\"; DO NOT EDIT.\n\npackage talos\n\nimport (\n\t\"github.com/hashicorp/terraform-plugin-framework/attr\"\n\t\"github.com/hashicorp/terraform-plugin-framework/datasource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/siderolabs/gen/xslices\"\n\t\"github.com/siderolabs/talos/pkg/machinery/resources/block\"\n)\n\ntype diskspec struct {\n\tDevPath        types.String `tfsdk:\"dev_path\"`\n\tSize           types.Int64  `tfsdk:\"size\"`\n\tPrettySize     types.String `tfsdk:\"pretty_size\"`\n\tIOSize         types.Int64  `tfsdk:\"io_size\"`\n\tSectorSize     types.Int64  `tfsdk:\"sector_size\"`\n\tReadonly       types.Bool   `tfsdk:\"readonly\"`\n\tCDROM          types.Bool   `tfsdk:\"cdrom\"`\n\tModel          types.String `tfsdk:\"model\"`\n\tSerial         types.String `tfsdk:\"serial\"`\n\tModalias       types.String `tfsdk:\"modalias\"`\n\tWWID           types.String `tfsdk:\"wwid\"`\n\tUUID           types.String `tfsdk:\"uuid\"`\n\tBusPath        types.String `tfsdk:\"bus_path\"`\n\tSubSystem      types.String `tfsdk:\"sub_system\"`\n\tTransport      types.String `tfsdk:\"transport\"`\n\tRotational     types.Bool   `tfsdk:\"rotational\"`\n\tSecondaryDisks types.List   `tfsdk:\"secondary_disks\"`\n\tSymlinks       types.List   `tfsdk:\"symlinks\"`\n}\n\nvar diskspecAttributes = map[string]schema.Attribute{\n\t\"dev_path\": schema.StringAttribute{\n\t\tComputed: true,\n\t},\n\t\"size\": schema.Int64Attribute{\n\t\tComputed: true,\n\t},\n\t\"pretty_size\": schema.StringAttribute{\n\t\tComputed: true,\n\t},\n\t\"io_size\": schema.Int64Attribute{\n\t\tComputed: true,\n\t},\n\t\"sector_size\": schema.Int64Attribute{\n\t\tComputed: true,\n\t},\n\t\"readonly\": schema.BoolAttribute{\n\t\tComputed: true,\n\t},\n\t\"cdrom\": schema.BoolAttribute{\n\t\tComputed: true,\n\t},\n\t\"model\": schema.StringAttribute{\n\t\tComputed: true,\n\t},\n\t\"serial\": schema.StringAttribute{\n\t\tComputed: true,\n\t},\n\t\"modalias\": schema.StringAttribute{\n\t\tComputed: true,\n\t},\n\t\"wwid\": schema.StringAttribute{\n\t\tComputed: true,\n\t},\n\t\"uuid\": schema.StringAttribute{\n\t\tComputed: true,\n\t},\n\t\"bus_path\": schema.StringAttribute{\n\t\tComputed: true,\n\t},\n\t\"sub_system\": schema.StringAttribute{\n\t\tComputed: true,\n\t},\n\t\"transport\": schema.StringAttribute{\n\t\tComputed: true,\n\t},\n\t\"rotational\": schema.BoolAttribute{\n\t\tComputed: true,\n\t},\n\t\"secondary_disks\": schema.ListAttribute{\n\t\tElementType: types.StringType,\n\t\tComputed:    true,\n\t},\n\t\"symlinks\": schema.ListAttribute{\n\t\tElementType: types.StringType,\n\t\tComputed:    true,\n\t},\n}\n\nfunc diskspecToTFTypes(diskspecSpec block.DiskSpec) diskspec {\n\treturn diskspec{\n\t\tDevPath:    types.StringValue(diskspecSpec.DevPath),\n\t\tSize:       types.Int64Value(int64(diskspecSpec.Size)),\n\t\tPrettySize: types.StringValue(diskspecSpec.PrettySize),\n\t\tIOSize:     types.Int64Value(int64(diskspecSpec.IOSize)),\n\t\tSectorSize: types.Int64Value(int64(diskspecSpec.SectorSize)),\n\t\tReadonly:   types.BoolValue(diskspecSpec.Readonly),\n\t\tCDROM:      types.BoolValue(diskspecSpec.CDROM),\n\t\tModel:      types.StringValue(diskspecSpec.Model),\n\t\tSerial:     types.StringValue(diskspecSpec.Serial),\n\t\tModalias:   types.StringValue(diskspecSpec.Modalias),\n\t\tWWID:       types.StringValue(diskspecSpec.WWID),\n\t\tUUID:       types.StringValue(diskspecSpec.UUID),\n\t\tBusPath:    types.StringValue(diskspecSpec.BusPath),\n\t\tSubSystem:  types.StringValue(diskspecSpec.SubSystem),\n\t\tTransport:  types.StringValue(diskspecSpec.Transport),\n\t\tRotational: types.BoolValue(diskspecSpec.Rotational),\n\t\tSecondaryDisks: types.ListValueMust(types.StringType, xslices.Map(diskspecSpec.SecondaryDisks, func(s string) attr.Value {\n\t\t\treturn types.StringValue(s)\n\t\t})),\n\t\tSymlinks: types.ListValueMust(types.StringType, xslices.Map(diskspecSpec.Symlinks, func(s string) attr.Value {\n\t\t\treturn types.StringValue(s)\n\t\t})),\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_secrets_ephemeral_resource.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework/ephemeral\"\n\t\"github.com/hashicorp/terraform-plugin-framework/ephemeral/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/schema/validator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/generate/secrets\"\n\t\"github.com/siderolabs/talos/pkg/machinery/gendata\"\n\t\"golang.org/x/mod/semver\"\n)\n\nvar _ ephemeral.EphemeralResource = &talosMachineSecretsEphemeralResource{}\n\ntype talosMachineSecretsEphemeralResource struct{}\n\ntype talosMachineSecretsEphemeralResourceModel struct {\n\tTalosVersion        types.String        `tfsdk:\"talos_version\"`\n\tMachineSecrets      machineSecrets      `tfsdk:\"machine_secrets\"`\n\tClientConfiguration clientConfiguration `tfsdk:\"client_configuration\"`\n}\n\n// NewTalosMachineSecretsEphemeralResource implements the ephemeral.EphemeralResource interface.\nfunc NewTalosMachineSecretsEphemeralResource() ephemeral.EphemeralResource {\n\treturn &talosMachineSecretsEphemeralResource{}\n}\n\nfunc (r *talosMachineSecretsEphemeralResource) Metadata(_ context.Context, req ephemeral.MetadataRequest, resp *ephemeral.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_machine_secrets\"\n}\n\nfunc (r *talosMachineSecretsEphemeralResource) Schema(_ context.Context, _ ephemeral.SchemaRequest, resp *ephemeral.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tDescription: \"Generate machine secrets for Talos cluster. This is an ephemeral resource that does not persist secrets in Terraform state.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"talos_version\": schema.StringAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The Talos version contract used to generate the secrets. Example values: `v1.12`, `v1.12.1`, `1.12`, `1.12.1`\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\ttalosVersionValid(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"machine_secrets\": machineSecretsOutputSchemaAttribute(),\n\t\t\t\"client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The generated client configuration data\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (r *talosMachineSecretsEphemeralResource) Open(ctx context.Context, req ephemeral.OpenRequest, resp *ephemeral.OpenResponse) {\n\tvar obj types.Object\n\n\tdiags := req.Config.Get(ctx, &obj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar config talosMachineSecretsEphemeralResourceModel\n\n\tdiags = obj.As(ctx, &config, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\t// Apply defaults for talos_version if not set, matching the regular resource's\n\t// plan modifier behavior which uses the compiled-in Talos version\n\ttalosVersion := config.TalosVersion.ValueString()\n\tif talosVersion == \"\" {\n\t\ttalosVersion = semver.MajorMinor(gendata.VersionTag)\n\t}\n\n\tversionContract, err := validateVersionContract(talosVersion)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to validate talos version\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\t// Generate secrets\n\tsecretsBundle, err := secrets.NewBundle(secrets.NewFixedClock(time.Now()), versionContract)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to generate secrets bundle\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\t// Convert to model\n\ttemp, err := secretsBundleTomachineSecrets(secretsBundle)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to convert secrets bundle to machine secrets\", err.Error())\n\n\t\treturn\n\t}\n\n\t// Build the ephemeral model (without ID field)\n\tresult := talosMachineSecretsEphemeralResourceModel{\n\t\tTalosVersion:        types.StringValue(talosVersion),\n\t\tMachineSecrets:      temp.MachineSecrets,\n\t\tClientConfiguration: temp.ClientConfiguration,\n\t}\n\n\t// Set result - ephemeral resources use Result instead of State\n\tdiags = resp.Result.Set(ctx, &result)\n\tresp.Diagnostics.Append(diags...)\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_secrets_ephemeral_resource_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework/providerserver\"\n\t\"github.com/hashicorp/terraform-plugin-go/tfprotov6\"\n\t\"github.com/hashicorp/terraform-plugin-testing/echoprovider\"\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n\t\"github.com/hashicorp/terraform-plugin-testing/knownvalue\"\n\t\"github.com/hashicorp/terraform-plugin-testing/statecheck\"\n\t\"github.com/hashicorp/terraform-plugin-testing/tfjsonpath\"\n\t\"github.com/hashicorp/terraform-plugin-testing/tfversion\"\n\n\t\"github.com/siderolabs/terraform-provider-talos/pkg/talos\"\n)\n\n// testAccProtoV6ProviderFactoriesWithEcho includes both the talos provider and echo provider.\nvar testAccProtoV6ProviderFactoriesWithEcho = map[string]func() (tfprotov6.ProviderServer, error){\n\t\"talos\": providerserver.NewProtocol6WithError(talos.New()),\n\t\"echo\":  echoprovider.NewProviderServer(),\n}\n\n// TestAccTalosMachineSecretsEphemeralResource tests that:\n// 1. Ephemeral resource generates secrets\n// 2. Secrets can be passed to other resources via echo provider\n//\n// Uses the Echo Provider to test values set in ephemeral resources\n// see documentation here for more details:\n// https://developer.hashicorp.com/terraform/plugin/testing/acceptance-tests/ephemeral-resources#using-echo-provider-in-acceptance-tests\nfunc TestAccTalosMachineSecretsEphemeralResource(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nprovider \"echo\" {\n\tdata = ephemeral.talos_machine_secrets.this\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\t// Verify that the ephemeral resource provides client_configuration\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"client_configuration\").AtMapKey(\"ca_certificate\"), knownvalue.NotNull()),\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"client_configuration\").AtMapKey(\"client_certificate\"), knownvalue.NotNull()),\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"client_configuration\").AtMapKey(\"client_key\"), knownvalue.NotNull()),\n\n\t\t\t\t\t// Verify that machine_secrets are populated\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"machine_secrets\").AtMapKey(\"cluster\").AtMapKey(\"id\"), knownvalue.NotNull()),\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"machine_secrets\").AtMapKey(\"cluster\").AtMapKey(\"secret\"), knownvalue.NotNull()),\n\n\t\t\t\t\t// Verify bootstrap token exists\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"machine_secrets\").AtMapKey(\"secrets\").AtMapKey(\"bootstrap_token\"), knownvalue.NotNull()),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosMachineSecretsEphemeralResourceNotInState verifies that\n// ephemeral resources are not persisted to state by the framework.\nfunc TestAccTalosMachineSecretsEphemeralResourceNotInState(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `ephemeral \"talos_machine_secrets\" \"this\" {}`,\n\t\t\t},\n\t\t},\n\t})\n}\n\n// TestAccTalosMachineSecretsEphemeralResourceWithDefault tests generation\n// with default talos_version.\nfunc TestAccTalosMachineSecretsEphemeralResourceWithDefault(t *testing.T) {\n\tt.Parallel()\n\n\tresource.UnitTest(t, resource.TestCase{\n\t\tTerraformVersionChecks: []tfversion.TerraformVersionCheck{\n\t\t\ttfversion.SkipBelow(tfversion.Version1_10_0),\n\t\t},\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactoriesWithEcho,\n\t\tSteps: []resource.TestStep{\n\t\t\t{\n\t\t\t\tConfig: `\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nprovider \"echo\" {\n\tdata = {\n\t\tcluster_id = ephemeral.talos_machine_secrets.this.machine_secrets.cluster.id\n\t}\n}\n\nresource \"echo\" \"test\" {}\n`,\n\t\t\t\tConfigStateChecks: []statecheck.StateCheck{\n\t\t\t\t\tstatecheck.ExpectKnownValue(\"echo.test\", tfjsonpath.New(\"data\").AtMapKey(\"cluster_id\"), knownvalue.NotNull()),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_secrets_resource.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework/path\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier\"\n\t\"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier\"\n\t\"github.com/hashicorp/terraform-plugin-framework/schema/validator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types/basetypes\"\n\t\"github.com/hashicorp/terraform-plugin-log/tflog\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/generate/secrets\"\n\t\"github.com/siderolabs/talos/pkg/machinery/gendata\"\n\t\"go.yaml.in/yaml/v4\"\n\t\"golang.org/x/mod/semver\"\n)\n\nvar (\n\t_ resource.Resource                 = &talosMachineSecretsResource{}\n\t_ resource.ResourceWithUpgradeState = &talosMachineSecretsResource{}\n\t_ resource.ResourceWithImportState  = &talosMachineSecretsResource{}\n\t_ resource.ResourceWithModifyPlan   = &talosMachineSecretsResource{}\n)\n\n// OverridableTimeFunc is a function that returns the current time. It is used to allow tests to override the current time.\n//\n//nolint:gocritic\nvar OverridableTimeFunc = func() time.Time {\n\treturn time.Now()\n}\n\ntype talosMachineSecretsResource struct{}\n\ntype talosMachineSecretsResourceModelV0 struct {\n\tID             types.String `tfsdk:\"id\"`\n\tTalosVersion   types.String `tfsdk:\"talos_version\"`\n\tMachineSecrets types.String `tfsdk:\"machine_secrets\"`\n}\n\ntype talosMachineSecretsResourceModelV1 struct {\n\tID                  types.String        `tfsdk:\"id\"`\n\tTalosVersion        types.String        `tfsdk:\"talos_version\"`\n\tMachineSecrets      machineSecrets      `tfsdk:\"machine_secrets\"`\n\tClientConfiguration clientConfiguration `tfsdk:\"client_configuration\"`\n}\n\ntype clientConfiguration struct {\n\tCA   types.String `tfsdk:\"ca_certificate\"`\n\tCert types.String `tfsdk:\"client_certificate\"`\n\tKey  types.String `tfsdk:\"client_key\"`\n}\n\ntype machineSecrets struct {\n\tCluster    machineSecretsCluster    `tfsdk:\"cluster\"`\n\tSecrets    machineSecretsSecrets    `tfsdk:\"secrets\"`\n\tTrustdInfo machineSecretsTrustdInfo `tfsdk:\"trustdinfo\"`\n\tCerts      machineSecretsCerts      `tfsdk:\"certs\"`\n}\n\ntype machineSecretsCluster struct {\n\tID     types.String `tfsdk:\"id\"`\n\tSecret types.String `tfsdk:\"secret\"`\n}\n\ntype machineSecretsSecrets struct {\n\tBootstrapToken            types.String `tfsdk:\"bootstrap_token\"`\n\tSecretboxEncryptionSecret types.String `tfsdk:\"secretbox_encryption_secret\"`\n\tAESCBCEncryptionSecret    types.String `tfsdk:\"aescbc_encryption_secret\"`\n}\n\ntype machineSecretsTrustdInfo struct {\n\tToken types.String `tfsdk:\"token\"`\n}\n\ntype machineSecretsCerts struct {\n\tEtcd              machineSecretsCertKeyPair            `tfsdk:\"etcd\"`\n\tK8s               machineSecretsCertKeyPair            `tfsdk:\"k8s\"`\n\tK8sAggregator     machineSecretsCertKeyPair            `tfsdk:\"k8s_aggregator\"`\n\tK8sServiceAccount machineSecretsCertsK8sServiceAccount `tfsdk:\"k8s_serviceaccount\"`\n\tOS                machineSecretsCertKeyPair            `tfsdk:\"os\"`\n}\n\ntype machineSecretsCertsK8sServiceAccount struct {\n\tKey types.String `tfsdk:\"key\"`\n}\n\ntype machineSecretsCertKeyPair struct {\n\tCert types.String `tfsdk:\"cert\"`\n\tKey  types.String `tfsdk:\"key\"`\n}\n\n// NewTalosMachineSecretsResource implements the resource.Resource interface.\nfunc NewTalosMachineSecretsResource() resource.Resource {\n\treturn &talosMachineSecretsResource{}\n}\n\nfunc (r *talosMachineSecretsResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {\n\tresp.TypeName = req.ProviderTypeName + \"_machine_secrets\"\n}\n\nfunc (r *talosMachineSecretsResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {\n\tresp.Schema = schema.Schema{\n\t\tVersion:     1,\n\t\tDescription: \"Generate machine secrets for Talos cluster.\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\tDescription: \"The computed ID of the Talos cluster\",\n\t\t\t\tComputed:    true,\n\t\t\t\tPlanModifiers: []planmodifier.String{\n\t\t\t\t\tstringplanmodifier.UseStateForUnknown(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"talos_version\": schema.StringAttribute{\n\t\t\t\tOptional:    true,\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The Talos version contract used to generate the secrets. Example values: `v1.12`, `v1.12.1`, `1.12`, `1.12.1`\",\n\t\t\t\tValidators: []validator.String{\n\t\t\t\t\ttalosVersionValid(),\n\t\t\t\t},\n\t\t\t\tPlanModifiers: []planmodifier.String{\n\t\t\t\t\ttalosMachineFeaturesVersionDefaults(),\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"machine_secrets\": machineSecretsOutputSchemaAttribute(),\n\t\t\t\"client_configuration\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"ca_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The client CA certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_certificate\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tDescription: \"The client certificate\",\n\t\t\t\t\t},\n\t\t\t\t\t\"client_key\": schema.StringAttribute{\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\tDescription: \"The client key\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tComputed:    true,\n\t\t\t\tDescription: \"The generated client configuration data\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc machineSecretsOutputSchemaAttribute() schema.SingleNestedAttribute {\n\treturn schema.SingleNestedAttribute{\n\t\tDescription: \"The secrets for the talos cluster\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"cluster\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\t\t\tDescription: \"The cluster ID\",\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t},\n\t\t\t\t\t\"secret\": schema.StringAttribute{\n\t\t\t\t\t\tDescription: \"The cluster secret\",\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tDescription: \"The cluster secrets\",\n\t\t\t\tComputed:    true,\n\t\t\t},\n\t\t\t\"secrets\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"bootstrap_token\": schema.StringAttribute{\n\t\t\t\t\t\tDescription: \"The bootstrap token\",\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t},\n\t\t\t\t\t\"secretbox_encryption_secret\": schema.StringAttribute{\n\t\t\t\t\t\tDescription: \"The secretbox encryption secret\",\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t},\n\t\t\t\t\t\"aescbc_encryption_secret\": schema.StringAttribute{\n\t\t\t\t\t\tDescription: \"The AES-CBC encryption secret\",\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tDescription: \"kubernetes cluster secrets\",\n\t\t\t\tComputed:    true,\n\t\t\t},\n\t\t\t\"trustdinfo\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"token\": schema.StringAttribute{\n\t\t\t\t\t\tDescription: \"The trustd token\",\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tDescription: \"trustd secrets\",\n\t\t\t\tComputed:    true,\n\t\t\t},\n\t\t\t\"certs\": schema.SingleNestedAttribute{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"etcd\":           certSchema(),\n\t\t\t\t\t\"k8s\":            certSchema(),\n\t\t\t\t\t\"k8s_aggregator\": certSchema(),\n\t\t\t\t\t\"k8s_serviceaccount\": schema.SingleNestedAttribute{\n\t\t\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\t\t\"key\": schema.StringAttribute{\n\t\t\t\t\t\t\t\tDescription: \"The service account key\",\n\t\t\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t\t\t\tSensitive:   true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tDescription: \"The service account secrets\",\n\t\t\t\t\t\tComputed:    true,\n\t\t\t\t\t},\n\t\t\t\t\t\"os\": certSchema(),\n\t\t\t\t},\n\t\t\t\tComputed: true,\n\t\t\t},\n\t\t},\n\t\tComputed: true,\n\t}\n}\n\nfunc certSchema() schema.SingleNestedAttribute {\n\treturn schema.SingleNestedAttribute{\n\t\tDescription: \"The certificate and key pair\",\n\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\"cert\": schema.StringAttribute{\n\t\t\t\tDescription: \"certificate data\",\n\t\t\t\tComputed:    true,\n\t\t\t},\n\t\t\t\"key\": schema.StringAttribute{\n\t\t\t\tDescription: \"key data\",\n\t\t\t\tComputed:    true,\n\t\t\t\tSensitive:   true,\n\t\t\t},\n\t\t},\n\t\tComputed: true,\n\t}\n}\n\nfunc (r *talosMachineSecretsResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {\n\tvar obj types.Object\n\n\tdiags := req.Plan.Get(ctx, &obj)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar plan talosMachineSecretsResourceModelV1\n\n\tdiags = obj.As(ctx, &plan, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tversionContract, err := validateVersionContract(plan.TalosVersion.ValueString())\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to validate talos version\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\tsecretsBundle, err := secrets.NewBundle(secrets.NewFixedClock(time.Now()), versionContract)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\n\t\t\t\"failed to generate secrets bundle\",\n\t\t\terr.Error(),\n\t\t)\n\n\t\treturn\n\t}\n\n\tstate, err := secretsBundleTomachineSecrets(secretsBundle)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to convert secrets bundle to machine secrets\", err.Error())\n\n\t\treturn\n\t}\n\n\tstate.TalosVersion = plan.TalosVersion\n\n\t// Set state to fully populated data\n\tdiags = resp.State.Set(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n\nfunc (r *talosMachineSecretsResource) Read(_ context.Context, _ resource.ReadRequest, _ *resource.ReadResponse) {\n}\n\nfunc (r *talosMachineSecretsResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {\n\t// delete is a no-op\n\tif req.Plan.Raw.IsNull() {\n\t\treturn\n\t}\n\n\tclientConfigurationPath := path.Root(\"client_configuration\")\n\n\tvar obj types.Object\n\n\tresp.Diagnostics.Append(req.State.GetAttribute(ctx, clientConfigurationPath, &obj)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar clientConfigurationData clientConfiguration\n\n\tdiags := obj.As(ctx, &clientConfigurationData, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif clientConfigurationData.CA.IsNull() || clientConfigurationData.CA.IsUnknown() {\n\t\treturn\n\t}\n\n\tclientCertificate := clientConfigurationData.Cert.ValueString()\n\n\tclientCertificateBytes, err := base64ToBytes(clientCertificate)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to decode client certificate\", err.Error())\n\n\t\treturn\n\t}\n\n\tblock, _ := pem.Decode(clientCertificateBytes)\n\tif block == nil {\n\t\tresp.Diagnostics.AddError(\"failed to decode client certificate\", \"failed to parse PEM block\")\n\n\t\treturn\n\t}\n\n\tx509Cert, err := x509.ParseCertificate(block.Bytes)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to parse client certificate\", err.Error())\n\n\t\treturn\n\t}\n\n\t// check if NotAfter expires in a month\n\tif x509Cert.NotAfter.Before(OverridableTimeFunc().AddDate(0, 1, 0)) {\n\t\ttflog.Info(ctx, \"client certificate expires in a month, needs regeneration\")\n\n\t\tresp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, path.Root(\"client_configuration\").AtName(\"ca_certificate\"), types.StringUnknown())...)\n\t\tresp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, path.Root(\"client_configuration\").AtName(\"client_certificate\"), types.StringUnknown())...)\n\t\tresp.Diagnostics.Append(resp.Plan.SetAttribute(ctx, path.Root(\"client_configuration\").AtName(\"client_key\"), types.StringUnknown())...)\n\n\t\tif resp.Diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (r *talosMachineSecretsResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {\n\tvar talosVersion string\n\n\tdiags := req.Plan.GetAttribute(ctx, path.Root(\"talos_version\"), &talosVersion)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\t// Set state to fully populated data\n\tdiags = resp.State.SetAttribute(ctx, path.Root(\"talos_version\"), talosVersion)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tclientConfigurationPath := path.Root(\"client_configuration\")\n\n\tvar obj types.Object\n\n\tresp.Diagnostics.Append(req.State.GetAttribute(ctx, clientConfigurationPath, &obj)...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tvar clientConfigurationData clientConfiguration\n\n\tdiags = obj.As(ctx, &clientConfigurationData, basetypes.ObjectAsOptions{\n\t\tUnhandledNullAsEmpty:    true,\n\t\tUnhandledUnknownAsEmpty: true,\n\t})\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n\n\tif clientConfigurationData.CA.IsNull() || clientConfigurationData.CA.IsUnknown() {\n\t\treturn\n\t}\n\n\tclientCertificate := clientConfigurationData.Cert.ValueString()\n\n\tclientCertificateBytes, err := base64ToBytes(clientCertificate)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to decode client certificate\", err.Error())\n\n\t\treturn\n\t}\n\n\tblock, _ := pem.Decode(clientCertificateBytes)\n\tif block == nil {\n\t\tresp.Diagnostics.AddError(\"failed to decode client certificate\", \"failed to parse PEM block\")\n\n\t\treturn\n\t}\n\n\tx509Cert, err := x509.ParseCertificate(block.Bytes)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to parse client certificate\", err.Error())\n\n\t\treturn\n\t}\n\n\t// check if NotAfter expires in a month\n\tif x509Cert.NotAfter.Before(OverridableTimeFunc().AddDate(0, 1, 0)) {\n\t\ttflog.Info(ctx, \"client certificate expires in a month, regenerating\")\n\n\t\tvar obj types.Object\n\n\t\tdiags := req.State.Get(ctx, &obj)\n\t\tresp.Diagnostics.Append(diags...)\n\n\t\tif resp.Diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\n\t\tvar config talosMachineSecretsResourceModelV1\n\n\t\tdiags = obj.As(ctx, &config, basetypes.ObjectAsOptions{\n\t\t\tUnhandledNullAsEmpty:    true,\n\t\t\tUnhandledUnknownAsEmpty: true,\n\t\t})\n\t\tresp.Diagnostics.Append(diags...)\n\n\t\tif resp.Diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\n\t\tsecretsBundle, err := machineSecretsToSecretsBundle(config)\n\t\tif err != nil {\n\t\t\tresp.Diagnostics.AddError(\"failed to convert machine secrets to secrets bundle\", err.Error())\n\n\t\t\treturn\n\t\t}\n\n\t\tif secretsBundle.Clock == nil {\n\t\t\tsecretsBundle.Clock = secrets.NewFixedClock(time.Now())\n\t\t}\n\n\t\tstate, err := secretsBundleTomachineSecrets(secretsBundle)\n\t\tif err != nil {\n\t\t\tresp.Diagnostics.AddError(\"failed to convert secrets bundle to machine secrets\", err.Error())\n\n\t\t\treturn\n\t\t}\n\n\t\tresp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(\"client_configuration\").AtName(\"ca_certificate\"), &state.ClientConfiguration.CA)...)\n\t\tresp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(\"client_configuration\").AtName(\"client_certificate\"), &state.ClientConfiguration.Cert)...)\n\t\tresp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(\"client_configuration\").AtName(\"client_key\"), &state.ClientConfiguration.Key)...)\n\n\t\tif resp.Diagnostics.HasError() {\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (r *talosMachineSecretsResource) Delete(_ context.Context, _ resource.DeleteRequest, _ *resource.DeleteResponse) {\n}\n\nfunc talosMachineFeaturesVersionDefaults() planmodifier.String {\n\treturn &talosMachineFeaturesVersionPlanModifier{}\n}\n\ntype talosMachineFeaturesVersionPlanModifier struct{}\n\nvar _ planmodifier.String = (*talosMachineFeaturesVersionPlanModifier)(nil)\n\nfunc (apm *talosMachineFeaturesVersionPlanModifier) Description(_ context.Context) string {\n\treturn \"sets default value for talos_version if not set\"\n}\n\nfunc (apm *talosMachineFeaturesVersionPlanModifier) MarkdownDescription(ctx context.Context) string {\n\treturn apm.Description(ctx)\n}\n\nfunc (apm *talosMachineFeaturesVersionPlanModifier) PlanModifyString(_ context.Context, req planmodifier.StringRequest, res *planmodifier.StringResponse) {\n\tif req.ConfigValue.IsUnknown() {\n\t\treturn\n\t}\n\n\t// setting default value\n\tif req.PlanValue.IsUnknown() || req.PlanValue.IsNull() {\n\t\tres.PlanValue = basetypes.NewStringValue(semver.MajorMinor(gendata.VersionTag))\n\n\t\treturn\n\t}\n\n\tplanValue := \"v\" + strings.TrimPrefix(req.PlanValue.ValueString(), \"v\")\n\tstateValue := \"v\" + strings.TrimPrefix(req.StateValue.ValueString(), \"v\")\n\n\tif semver.Compare(planValue, stateValue) < 0 {\n\t\tres.RequiresReplace = true\n\t}\n}\n\nfunc (r *talosMachineSecretsResource) UpgradeState(_ context.Context) map[int64]resource.StateUpgrader {\n\treturn map[int64]resource.StateUpgrader{\n\t\t0: {\n\t\t\tPriorSchema: &schema.Schema{\n\t\t\t\tAttributes: map[string]schema.Attribute{\n\t\t\t\t\t\"id\": schema.StringAttribute{\n\t\t\t\t\t\tComputed: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"talos_version\": schema.StringAttribute{\n\t\t\t\t\t\tOptional: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"machine_secrets\": schema.StringAttribute{\n\t\t\t\t\t\tComputed: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tStateUpgrader: func(ctx context.Context, req resource.UpgradeStateRequest, resp *resource.UpgradeStateResponse) {\n\t\t\t\tvar priorStateData talosMachineSecretsResourceModelV0\n\n\t\t\t\tdiags := req.State.Get(ctx, &priorStateData)\n\t\t\t\tresp.Diagnostics.Append(diags...)\n\n\t\t\t\tif resp.Diagnostics.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tvar secretsBundle *secrets.Bundle\n\t\t\t\tif err := yaml.Unmarshal([]byte(priorStateData.MachineSecrets.ValueString()), &secretsBundle); err != nil {\n\t\t\t\t\tresp.Diagnostics.AddError(\"failed to unmarshal machine secrets\", err.Error())\n\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tstate, err := secretsBundleTomachineSecrets(secretsBundle)\n\t\t\t\tif err != nil {\n\t\t\t\t\tresp.Diagnostics.AddError(\"failed to convert secrets bundle to machine secrets\", err.Error())\n\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tstate.TalosVersion = basetypes.NewStringValue(\"v1.3\")\n\n\t\t\t\tif secretsBundle.Secrets.AESCBCEncryptionSecret != \"\" {\n\t\t\t\t\tstate.TalosVersion = basetypes.NewStringValue(\"v1.2\")\n\t\t\t\t}\n\n\t\t\t\t// Set state to fully populated data\n\t\t\t\tdiags = resp.State.Set(ctx, &state)\n\t\t\t\tresp.Diagnostics.Append(diags...)\n\n\t\t\t\tif resp.Diagnostics.HasError() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (r *talosMachineSecretsResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {\n\tid := req.ID\n\n\tif _, err := os.Stat(id); err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to import state\", err.Error())\n\n\t\treturn\n\t}\n\n\tsecretBytes, err := os.ReadFile(id)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to read machine secrets file\", err.Error())\n\n\t\treturn\n\t}\n\n\tvar secretsBundle *secrets.Bundle\n\tif err = yaml.Unmarshal(secretBytes, &secretsBundle); err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to unmarshal machine secrets\", err.Error())\n\n\t\treturn\n\t}\n\n\tstate, err := secretsBundleTomachineSecrets(secretsBundle)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"failed to convert secrets bundle to machine secrets\", err.Error())\n\n\t\treturn\n\t}\n\n\tstate.TalosVersion = basetypes.NewStringValue(\"v1.3\")\n\n\tif secretsBundle.Secrets.AESCBCEncryptionSecret != \"\" {\n\t\tstate.TalosVersion = basetypes.NewStringValue(\"v1.2\")\n\t}\n\n\t// Set state to fully populated data\n\tdiags := resp.State.Set(ctx, &state)\n\tresp.Diagnostics.Append(diags...)\n\n\tif resp.Diagnostics.HasError() {\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "pkg/talos/talos_machine_secrets_resource_test.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-testing/helper/resource\"\n\t\"github.com/hashicorp/terraform-plugin-testing/plancheck\"\n\t\"github.com/siderolabs/talos/pkg/machinery/gendata\"\n\t\"golang.org/x/mod/semver\"\n\n\t\"github.com/siderolabs/terraform-provider-talos/pkg/talos\"\n)\n\n//nolint:maintidx\nfunc TestAccTalosMachineSecretsResource(t *testing.T) {\n\ttestTime := time.Now()\n\n\tresource.Test(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t// test defaults\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"id\", \"machine_secrets\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"talos_version\", semver.MajorMinor(gendata.VersionTag)),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.id\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.secret\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.bootstrap_token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.secretbox_encryption_secret\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.trustdinfo.token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_serviceaccount.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_key\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.secrets.aescbc_encryption_secret\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// test talosconfig regeneration\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tPreConfig: func() {\n\t\t\t\t\ttalos.OverridableTimeFunc = func() time.Time {\n\t\t\t\t\t\treturn testTime.AddDate(0, 12, 5)\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tPlanOnly:           true,\n\t\t\t\tExpectNonEmptyPlan: true,\n\t\t\t},\n\t\t},\n\t})\n\n\ttalos.OverridableTimeFunc = func() time.Time {\n\t\treturn testTime\n\t}\n\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t// test defaults\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"id\", \"machine_secrets\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"talos_version\", semver.MajorMinor(gendata.VersionTag)),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.id\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.secret\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.bootstrap_token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.secretbox_encryption_secret\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.trustdinfo.token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_serviceaccount.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_key\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.secrets.aescbc_encryption_secret\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// test that setting the talos_version to the same value does not cause a diff\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineSecretsResourceConfig(semver.MajorMinor(gendata.VersionTag)),\n\t\t\t\tPreConfig: func() {\n\t\t\t\t\ttalos.OverridableTimeFunc = func() time.Time {\n\t\t\t\t\t\treturn testTime\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tConfigPlanChecks: resource.ConfigPlanChecks{\n\t\t\t\t\tPreApply: []plancheck.PlanCheck{\n\t\t\t\t\t\tplancheck.ExpectEmptyPlan(),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"id\", \"machine_secrets\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"talos_version\", semver.MajorMinor(gendata.VersionTag)),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.id\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.secret\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.bootstrap_token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.secretbox_encryption_secret\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.trustdinfo.token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_serviceaccount.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_key\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.secrets.aescbc_encryption_secret\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// test that setting the talos_version to a lower version causes a diff and requires replacement\n\t\t\t// also test that the aescbc_encryption_secret is set\n\t\t\t{ //nolint:dupl\n\t\t\t\tConfig: testAccTalosMachineSecretsResourceConfig(\"v1.2.0\"),\n\t\t\t\tConfigPlanChecks: resource.ConfigPlanChecks{\n\t\t\t\t\tPreApply: []plancheck.PlanCheck{\n\t\t\t\t\t\tplancheck.ExpectNonEmptyPlan(),\n\t\t\t\t\t\tplancheck.ExpectResourceAction(\"talos_machine_secrets.this\", plancheck.ResourceActionReplace),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"id\", \"machine_secrets\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"talos_version\", \"v1.2.0\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.id\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.secret\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.bootstrap_token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.trustdinfo.token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_serviceaccount.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.aescbc_encryption_secret\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// test that setting the talos_version to a higher version does not cause a diff and requires no replacement\n\t\t\t// also test that the aescbc_encryption_secret is still set when upgrading\n\t\t\t{ //nolint:dupl\n\t\t\t\tConfig: testAccTalosMachineSecretsResourceConfig(\"1.4\"),\n\t\t\t\tConfigPlanChecks: resource.ConfigPlanChecks{\n\t\t\t\t\tPreApply: []plancheck.PlanCheck{\n\t\t\t\t\t\tplancheck.ExpectNonEmptyPlan(),\n\t\t\t\t\t\tplancheck.ExpectResourceAction(\"talos_machine_secrets.this\", plancheck.ResourceActionUpdate),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"id\", \"machine_secrets\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"talos_version\", \"1.4\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.id\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.secret\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.bootstrap_token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.trustdinfo.token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_serviceaccount.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.ca_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.aescbc_encryption_secret\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n\n\tresource.Test(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t// test importing from a secrets.yaml file\n\t\t\t{\n\t\t\t\tConfig:             testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tResourceName:       \"talos_machine_secrets.this\",\n\t\t\t\tImportState:        true,\n\t\t\t\tImportStatePersist: true,\n\t\t\t\tImportStateId:      \"testdata/secrets.yaml\",\n\t\t\t},\n\t\t\t// verify there are no changes after import\n\t\t\t{\n\t\t\t\tConfig:   testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tPlanOnly: true,\n\t\t\t},\n\t\t\t// verify state is correct after import\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"id\", \"machine_secrets\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"talos_version\", \"v1.3\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.cluster.id\", \"_u8NZvwQ9ObtEN7iTzc-OEpk20K-rnO3FNcjvVEQ84Q=\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.cluster.secret\", \"UnZE8oq6qPNI8tuw+WF3PGi2Zba0RQuit/aJTflOau8=\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.secrets.bootstrap_token\", \"m2wfba.pcyzhp6rf6pubqtk\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.secrets.secretbox_encryption_secret\", \"avDR6jwn4iYS6sTOH689P2UcNUlh3UsuO+FaOKI2hls=\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.trustdinfo.token\", \"s5lcto.f2ythdlx6avcsny9\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.cert\", \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJmakNDQVNTZ0F3SUJBZ0lSQUt6KzNQbkZYWHNTdXNQb3RLTnVabG93Q2dZSUtvWkl6ajBFQXdJd0R6RU4KTUFzR0ExVUVDaE1FWlhSalpEQWVGdzB5TXpBME1ERXhORE01TURaYUZ3MHpNekF6TWpreE5ETTVNRFphTUE4eApEVEFMQmdOVkJBb1RCR1YwWTJRd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTbGFaU0p1UnhMCit4NDdYelY5OWIwaEd1dmdybGZrUnFEdStVUWlrSFJlRCtFL3VZUXprc1ArZTFLMVBUcFJVTG45ZEJYY21jd1AKazY2UXRCN09mQ0pEbzJFd1h6QU9CZ05WSFE4QkFmOEVCQU1DQW9Rd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSApBd0VHQ0NzR0FRVUZCd01DTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRk5kVHVVdmduZXcwCkJSa0dZRnJueWNpWFZjUTdNQW9HQ0NxR1NNNDlCQU1DQTBnQU1FVUNJUURJZGVqQ3ppL25xb3h0eUp3QnROTEYKTDE3UWdqQjNzMFoySUV5ZDZPTE51UUlnY0lHcWRWemJKQ3dXSkZXSWxnWWVyUGZvZzdzUjFxMWdKV25ST3p4UApBakE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"),                        //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.key\", \"LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUoxWVI2ck9pd3N2TmRWZFErVnpiQ1hlRlBEbGJ1cDVUM1ZidnJrVDM2M1NvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFcFdtVWlia2NTL3NlTzE4MWZmVzlJUnJyNEs1WDVFYWc3dmxFSXBCMFhnL2hQN21FTTVMRAovbnRTdFQwNlVWQzUvWFFWM0puTUQ1T3VrTFFlem53aVF3PT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\"),                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.cert\", \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJpakNDQVMrZ0F3SUJBZ0lRSE5COFFlVjRtazlUR3k4amtTUGtYVEFLQmdncWhrak9QUVFEQWpBVk1STXcKRVFZRFZRUUtFd3ByZFdKbGNtNWxkR1Z6TUI0WERUSXpNRFF3TVRFME16a3dObG9YRFRNek1ETXlPVEUwTXprdwpObG93RlRFVE1CRUdBMVVFQ2hNS2EzVmlaWEp1WlhSbGN6QlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VICkEwSUFCQVBKQjEwL3RnVFlkdVhrS0h6SVFEZDNLbW54MithbmFXcGN3RUlhWlhMbnNsRHRycGU3ancwaXRVK1oKa2w2eEd5STk4M0FpRkxWc004cHhra3RoZ2tTallUQmZNQTRHQTFVZER3RUIvd1FFQXdJQ2hEQWRCZ05WSFNVRQpGakFVQmdnckJnRUZCUWNEQVFZSUt3WUJCUVVIQXdJd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFCkZnUVU1K0hGd29PbTdURWhpcm1DTGt2SllyRmRQc293Q2dZSUtvWkl6ajBFQXdJRFNRQXdSZ0loQU1WZFNVUEUKcGlNWkpkNHNYV1pvdzdLb0djWWhPb1NtcDJkaUZEdUEzMjcyQWlFQTRuamcwN2ZhVEFGck1SUGF4SmFIMVhsdQpKTHBPMTh0bHZhVlVFMW5XY2xnPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\"), //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.key\", \"LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUZJQ0crOUR1Wm9YU0xiVjRWK1VoZkdRUWV5OUJ3dWEwZUx6M0hTU1hyMmhvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFQThrSFhUKzJCTmgyNWVRb2ZNaEFOM2NxYWZIYjVxZHBhbHpBUWhwbGN1ZXlVTzJ1bDd1UApEU0sxVDVtU1hyRWJJajN6Y0NJVXRXd3p5bkdTUzJHQ1JBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\"),                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.cert\", \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJZVENDQVFhZ0F3SUJBZ0lSQUtDY3hEVUM4UG9GK3pSajJWVlJLWTR3Q2dZSUtvWkl6ajBFQXdJd0FEQWUKRncweU16QTBNREV4TkRNNU1EWmFGdzB6TXpBek1qa3hORE01TURaYU1BQXdXVEFUQmdjcWhrak9QUUlCQmdncQpoa2pPUFFNQkJ3TkNBQVFPUjZKcTl1ekp3RWNFZnowc1dKdERVejhwNUpseHRJZkJjTTMzRFJ5cDhCSDZGQTFCCjJiUkx5ZTBsU3p6TXFmdVpFblhxOE9qazdobklGSUdsNlVNaW8yRXdYekFPQmdOVkhROEJBZjhFQkFNQ0FvUXcKSFFZRFZSMGxCQll3RkFZSUt3WUJCUVVIQXdFR0NDc0dBUVVGQndNQ01BOEdBMVVkRXdFQi93UUZNQU1CQWY4dwpIUVlEVlIwT0JCWUVGQUpPaUFGNTRhUXRPaUpzdFU2U2Z1QWpGOFJwTUFvR0NDcUdTTTQ5QkFNQ0Ewa0FNRVlDCklRREdPOUhXVXNaZlozRUdJTEdGRjJwUDIwUGNjSDZMV2hZSjg1eHB2RDBOSGdJaEFOOHFpVElXYVF2dUs3M1cKVENwT2g5TU1PS2o1YmFNcEh6M2FJOGVMZHBiVAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\"),                                                                  //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.key\", \"LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU4rRDdGWGJoUTg4c1d6eEJPSXZtMVJVVVBtT25VeFBCRGlvR21mL1dnMjlvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFRGtlaWF2YnN5Y0JIQkg4OUxGaWJRMU0vS2VTWmNiU0h3WEROOXcwY3FmQVIraFFOUWRtMApTOG50SlVzOHpLbjdtUkoxNnZEbzVPNFp5QlNCcGVsRElnPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\"),                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_serviceaccount.key\", \"LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUVabmsrN2djSXBLdC8vM2lrQ1dLZm5SNnFjeWY5bHVyK1lGbzQyTlhVVVlvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFeG9rOTBEbnI2MGRYQ3BhQmxUMnVJUnRjdUJPLytCVjZEajVPaWYvTGVwSS95NktlQ2lRTApwRGZxenNHQW5zQXkrVHI3SWNxSUlROGZGaXRtK0t5emJBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\"),                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.cert\", \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJQekNCOHFBREFnRUNBaEVBM0E0TEZ3cDVTZG5wTXVmYlp3NHVpekFGQmdNclpYQXdFREVPTUF3R0ExVUUKQ2hNRmRHRnNiM013SGhjTk1qTXdOREF4TVRRek9UQTJXaGNOTXpNd016STVNVFF6T1RBMldqQVFNUTR3REFZRApWUVFLRXdWMFlXeHZjekFxTUFVR0F5dGxjQU1oQUZ2TWUyeHFzSk9WemkvY0xLNXVXVzU2VmZZK29nWlYvQVowCmxlTFdtTWl1bzJFd1h6QU9CZ05WSFE4QkFmOEVCQU1DQW9Rd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSEF3RUcKQ0NzR0FRVUZCd01DTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRkxqK3VablllVFFUdEdmUgpOeVVQYWh6dzNkdkhNQVVHQXl0bGNBTkJBQVg4cVhJNm4ydlk3ZGxnZGtxckUvN25ua2kwTzFtVERDL3dBamlwCmpaemY5QmhocEdRUXFYSkxHdlhJTnRDaXN5KzQrcTVtOUVjUUpMMXF4UWdOdndnPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\"),                                                                                                                                          //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.key\", \"LS0tLS1CRUdJTiBFRDI1NTE5IFBSSVZBVEUgS0VZLS0tLS0KTUM0Q0FRQXdCUVlESzJWd0JDSUVJSlVlQmxic3hhMW0vR1B0NTZCeVIvZ1Z3YWRzVmdkc3pXZEh4MWZiZ0c4VwotLS0tLUVORCBFRDI1NTE5IFBSSVZBVEUgS0VZLS0tLS0K\"),                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"client_configuration.ca_certificate\", \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJQekNCOHFBREFnRUNBaEVBM0E0TEZ3cDVTZG5wTXVmYlp3NHVpekFGQmdNclpYQXdFREVPTUF3R0ExVUUKQ2hNRmRHRnNiM013SGhjTk1qTXdOREF4TVRRek9UQTJXaGNOTXpNd016STVNVFF6T1RBMldqQVFNUTR3REFZRApWUVFLRXdWMFlXeHZjekFxTUFVR0F5dGxjQU1oQUZ2TWUyeHFzSk9WemkvY0xLNXVXVzU2VmZZK29nWlYvQVowCmxlTFdtTWl1bzJFd1h6QU9CZ05WSFE4QkFmOEVCQU1DQW9Rd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSEF3RUcKQ0NzR0FRVUZCd01DTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRkxqK3VablllVFFUdEdmUgpOeVVQYWh6dzNkdkhNQVVHQXl0bGNBTkJBQVg4cVhJNm4ydlk3ZGxnZGtxckUvN25ua2kwTzFtVERDL3dBamlwCmpaemY5QmhocEdRUXFYSkxHdlhJTnRDaXN5KzQrcTVtOUVjUUpMMXF4UWdOdndnPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\"),                                                                                                                                    //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_key\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.secrets.aescbc_encryption_secret\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n\n\tresource.Test(t, resource.TestCase{\n\t\tIsUnitTest:               true, // this is a local only resource, so can be unit tested\n\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\tSteps: []resource.TestStep{\n\t\t\t// test importing from a v1.2 secrets file\n\t\t\t{\n\t\t\t\tConfig:             testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tResourceName:       \"talos_machine_secrets.this\",\n\t\t\t\tImportState:        true,\n\t\t\t\tImportStatePersist: true,\n\t\t\t\tImportStateId:      \"testdata/secretsv1.2.yaml\",\n\t\t\t},\n\t\t\t// verify that there are no diffs\n\t\t\t{\n\t\t\t\tConfig:   testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tPlanOnly: true,\n\t\t\t},\n\t\t\t// verify state is correct after import\n\t\t\t{\n\t\t\t\tConfig: testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"id\", \"machine_secrets\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"talos_version\", \"v1.2\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.cluster.id\", \"q_I385nl7MWqU1UpW224rQyZW4TWd_WmnxsA2MQLsl8=\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.cluster.secret\", \"1szT7qMuensSCcSVRtnFsG0pbXMLMSZ8r5wu/41aJBc=\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.secrets.bootstrap_token\", \"5co9z6.qnnjtotc5ffntt62\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.secrets.secretbox_encryption_secret\", \"\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.trustdinfo.token\", \"o2q4ek.ofdeihu3li44x7lr\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.cert\", \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJmakNDQVNTZ0F3SUJBZ0lSQU8rYmlXSlFJdHZXZUZ0UUNEVDhwRXd3Q2dZSUtvWkl6ajBFQXdJd0R6RU4KTUFzR0ExVUVDaE1FWlhSalpEQWVGdzB5TXpBME1ERXhOVFF4TURSYUZ3MHpNekF6TWpreE5UUXhNRFJhTUE4eApEVEFMQmdOVkJBb1RCR1YwWTJRd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFReHRnaFlZV1AvCngzWGFBM1RPVXd4Y1AySlh2QVYzdllaS2I1SENKK0E2M2dieE50dW5Gcm03NW8rK0ZQQndYdUtZUmMrU09pTXEKdWY5bjdkZmY4cUJKbzJFd1h6QU9CZ05WSFE4QkFmOEVCQU1DQW9Rd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSApBd0VHQ0NzR0FRVUZCd01DTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRkU2VUVneitoOSsvCnZYdnNod1d2bHJvQkh6SlFNQW9HQ0NxR1NNNDlCQU1DQTBnQU1FVUNJUUQ3YTFzMy91cmRybFlxaXJxTmN6aTIKTm5qNVFCdFVmczFNYkNqNTdkYXR3d0lnZlJYdEIyWVZMUy9OMFVQTDkxekhITCtLM09EaEZ2M1dsc0gwMlpmdgpMNHc9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\"),                        //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.key\", \"LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUJDNUpZQmgzWWQ2NnJwWkcvTHZEMWt4SFRvWTA4QnZsQkpMcy9aZXR4NldvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFTWJZSVdHRmovOGQxMmdOMHpsTU1YRDlpVjd3RmQ3MkdTbStSd2lmZ090NEc4VGJicHhhNQp1K2FQdmhUd2NGN2ltRVhQa2pvaktybi9aKzNYMy9LZ1NRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\"),                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.cert\", \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJpVENDQVMrZ0F3SUJBZ0lRVW9hWGkyZGxUWHk1alNBUVdvSUZOVEFLQmdncWhrak9QUVFEQWpBVk1STXcKRVFZRFZRUUtFd3ByZFdKbGNtNWxkR1Z6TUI0WERUSXpNRFF3TVRFMU5ERXdORm9YRFRNek1ETXlPVEUxTkRFdwpORm93RlRFVE1CRUdBMVVFQ2hNS2EzVmlaWEp1WlhSbGN6QlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VICkEwSUFCRWJieTQreTdIWmZUcVNNaDRtMWx3a3E3THE5WUtWdVhmV3BJLzZ4K1orZC9uUFJFNFA0eGhNUklKL3oKZHl4TDJxTGNSOUcxV3pjVWJBRVYrMjliUWNDallUQmZNQTRHQTFVZER3RUIvd1FFQXdJQ2hEQWRCZ05WSFNVRQpGakFVQmdnckJnRUZCUWNEQVFZSUt3WUJCUVVIQXdJd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFCkZnUVUzRG8xb2MzM054dWhYRTJ4M2NvbHM3a2dWWmN3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUloQU9pb3RHR1MKNnJLdWFoT2twMlQ5NjRzSUhhdmx3bUJqZ0ljVkI1dTFPV2RsQWlBRXZKUUVTRGNBZWlmVm1seG1pdWVDMHl4SQowODBqY2FxUjdUVWNjaHhrSnc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\"), //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.key\", \"LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUx5bm9FaURjeG1NL3ZlL1B1R0YwWFNjeEgydG10SGZSdVU0SkVvejBGRmtvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFUnR2TGo3THNkbDlPcEl5SGliV1hDU3JzdXIxZ3BXNWQ5YWtqL3JINW41MytjOUVUZy9qRwpFeEVnbi9OM0xFdmFvdHhIMGJWYk54UnNBUlg3YjF0QndBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\"),                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.cert\", \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJZRENDQVFhZ0F3SUJBZ0lSQUp5THJmLzk5aE00a1ZNWTJraFd4TjR3Q2dZSUtvWkl6ajBFQXdJd0FEQWUKRncweU16QTBNREV4TlRReE1EUmFGdzB6TXpBek1qa3hOVFF4TURSYU1BQXdXVEFUQmdjcWhrak9QUUlCQmdncQpoa2pPUFFNQkJ3TkNBQVFZTTBWWUVZWTVOaURlNHp6Z21mYlJSdDRNalRmOUlyeUVVcms1SjNPRFQzYkFpanVDCmd6eWpmTkZIbFlXbm9PcWZBeGpjVVVsQkU2L2xuRmdiMzNwUW8yRXdYekFPQmdOVkhROEJBZjhFQkFNQ0FvUXcKSFFZRFZSMGxCQll3RkFZSUt3WUJCUVVIQXdFR0NDc0dBUVVGQndNQ01BOEdBMVVkRXdFQi93UUZNQU1CQWY4dwpIUVlEVlIwT0JCWUVGTHBKUEhhRGw1UjY4NjlDNEVyVXF5WHhBeUpWTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDCklFc0VlOElSNEwvK3phMC9CbzlUNGRKbERpQ3VDK1BSd1JueXE4OEE5dFUvQWlFQTBGUXNJcGk5V1ZiU2krODQKQkVCaGRWTkpmQUVUYTZVQ2UrTWFsNUJRUjlrPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\"),                                                                  //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.key\", \"LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUMxSDViQUY5RkJWQzVIQjZ2dzJwL1FRUFkvWEVjdzhaTUJ0ZDZFTmw3cXFvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFR0RORldCR0dPVFlnM3VNODRKbjIwVWJlREkwMy9TSzhoRks1T1NkemcwOTJ3SW83Z29NOApvM3pSUjVXRnA2RHFud01ZM0ZGSlFST3Y1WnhZRzk5NlVBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\"),                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_serviceaccount.key\", \"LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUxHRjlhcmp4SEdyMExMbTdMTjg0Ympjbml2RWpGSkxlUFNvVGhZUS9maWdvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFNjRuQVlld3hqeVkrVkY4MDZ5WU5iU3pnNEl4cFh6TW1hMW93b3FjbDc5elZtMkRsbHcxUApYR3FTZ0hpWUxwcjZ1ZU5OeSswcXdOdklCU3RKSXZLVzNnPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\"),                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.cert\", \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJQakNCOGFBREFnRUNBaEIzcXY0bDNhTStSaGFsWmdHOGowdDNNQVVHQXl0bGNEQVFNUTR3REFZRFZRUUsKRXdWMFlXeHZjekFlRncweU16QTBNREV4TlRReE1EUmFGdzB6TXpBek1qa3hOVFF4TURSYU1CQXhEakFNQmdOVgpCQW9UQlhSaGJHOXpNQ293QlFZREsyVndBeUVBWk1TT1d4aHF4UThEbHdUVmszM2xRN09ydDAvOTE5b0JXTVpUCmRSU3Q4SGFqWVRCZk1BNEdBMVVkRHdFQi93UUVBd0lDaERBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFRWUkKS3dZQkJRVUhBd0l3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVYkhDeHcyOTd4RHc3Tjh0SQpDQTJTUDc2K3Q5OHdCUVlESzJWd0EwRUFrcnQ1UEVnZ2JZNFFlYnNIa2lDTmZlMFpZNlE1UmZhVm52TVRxOE1lCnRhSktTQ1NPYTljczh2dXVDMnl2QmNSU0hPWldocG9WaW05bXhEaVc3TDZTQXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\"),                                                                                                                                          //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.key\", \"LS0tLS1CRUdJTiBFRDI1NTE5IFBSSVZBVEUgS0VZLS0tLS0KTUM0Q0FRQXdCUVlESzJWd0JDSUVJRjdtNmJKWHNOd3F4ejFMaXRnVlFJSEx5WDJab1hadW85UTNEZjRGSThWaAotLS0tLUVORCBFRDI1NTE5IFBSSVZBVEUgS0VZLS0tLS0K\"),                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"client_configuration.ca_certificate\", \"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJQakNCOGFBREFnRUNBaEIzcXY0bDNhTStSaGFsWmdHOGowdDNNQVVHQXl0bGNEQVFNUTR3REFZRFZRUUsKRXdWMFlXeHZjekFlRncweU16QTBNREV4TlRReE1EUmFGdzB6TXpBek1qa3hOVFF4TURSYU1CQXhEakFNQmdOVgpCQW9UQlhSaGJHOXpNQ293QlFZREsyVndBeUVBWk1TT1d4aHF4UThEbHdUVmszM2xRN09ydDAvOTE5b0JXTVpUCmRSU3Q4SGFqWVRCZk1BNEdBMVVkRHdFQi93UUVBd0lDaERBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFRWUkKS3dZQkJRVUhBd0l3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVYkhDeHcyOTd4RHc3Tjh0SQpDQTJTUDc2K3Q5OHdCUVlESzJWd0EwRUFrcnQ1UEVnZ2JZNFFlYnNIa2lDTmZlMFpZNlE1UmZhVm52TVRxOE1lCnRhSktTQ1NPYTljczh2dXVDMnl2QmNSU0hPWldocG9WaW05bXhEaVc3TDZTQXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\"),                                                                                                                                    //nolint:lll\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_certificate\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"client_configuration.client_key\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.secrets.aescbc_encryption_secret\", \"hLrjDIpZ8gSGwejFfnUnjOrn9PQ7Bj3yq/ggAgD9AHA=\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestAccTalosMachineSecretsResourceUpgrade1(t *testing.T) {\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tIsUnitTest: true, // this is a local only resource, so can be unit tested\n\t\tSteps: []resource.TestStep{\n\t\t\t// create talos_machine_secrets resource with talos version 0.1.2\n\t\t\t{\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"talos\": {\n\t\t\t\t\t\tVersionConstraint: \"=0.1.2\",\n\t\t\t\t\t\tSource:            \"siderolabs/talos\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tConfig: testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"id\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_secrets.this\", \"talos_version\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// verify the new state is compatible with the latest version of the provider\n\t\t\t{\n\t\t\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\t\t\tConfig:                   testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"id\", \"machine_secrets\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"talos_version\", \"v1.3\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.id\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.secret\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.bootstrap_token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.secretbox_encryption_secret\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.trustdinfo.token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_serviceaccount.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.key\"),\n\t\t\t\t\tresource.TestCheckNoResourceAttr(\"talos_machine_secrets.this\", \"machine_secrets.secrets.aescbc_encryption_secret\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestAccTalosMachineSecretsResourceUpgrade2(t *testing.T) { //nolint:dupl\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tIsUnitTest: true, // this is a local only resource, so can be unit tested\n\t\tSteps: []resource.TestStep{\n\t\t\t// create talos_machine_secrets resource with talos version 0.1.2\n\t\t\t{\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"talos\": {\n\t\t\t\t\t\tVersionConstraint: \"=0.1.2\",\n\t\t\t\t\t\tSource:            \"siderolabs/talos\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tConfig: testAccTalosMachineSecretsResourceConfig(\"v1.2\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"id\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"talos_version\", \"v1.2\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// verify the new state is compatible with the latest version of the provider\n\t\t\t{\n\t\t\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\t\t\tConfig:                   testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"id\", \"machine_secrets\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"talos_version\", \"v1.2\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.id\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.secret\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.bootstrap_token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.trustdinfo.token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_serviceaccount.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.aescbc_encryption_secret\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestAccTalosMachineSecretsResourceUpgrade3(t *testing.T) { //nolint:dupl\n\tresource.ParallelTest(t, resource.TestCase{\n\t\tIsUnitTest: true, // this is a local only resource, so can be unit tested\n\t\tSteps: []resource.TestStep{\n\t\t\t// create talos_machine_secrets resource with talos version 0.1.2\n\t\t\t{\n\t\t\t\tExternalProviders: map[string]resource.ExternalProvider{\n\t\t\t\t\t\"talos\": {\n\t\t\t\t\t\tVersionConstraint: \"=0.1.2\",\n\t\t\t\t\t\tSource:            \"siderolabs/talos\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tConfig: testAccTalosMachineSecretsResourceConfig(\"v1.1\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"id\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"talos_version\", \"v1.1\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets\"),\n\t\t\t\t),\n\t\t\t},\n\t\t\t// verify the new state is compatible with the latest version of the provider\n\t\t\t{\n\t\t\t\tProtoV6ProviderFactories: testAccProtoV6ProviderFactories,\n\t\t\t\tConfig:                   testAccTalosMachineSecretsResourceConfig(\"\"),\n\t\t\t\tCheck: resource.ComposeAggregateTestCheckFunc(\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"id\", \"machine_secrets\"),\n\t\t\t\t\tresource.TestCheckResourceAttr(\"talos_machine_secrets.this\", \"talos_version\", \"v1.2\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.id\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.cluster.secret\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.bootstrap_token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.trustdinfo.token\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.etcd.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_aggregator.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.k8s_serviceaccount.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.cert\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.certs.os.key\"),\n\t\t\t\t\tresource.TestCheckResourceAttrSet(\"talos_machine_secrets.this\", \"machine_secrets.secrets.aescbc_encryption_secret\"),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc testAccTalosMachineSecretsResourceConfig(talosConfigVersion string) string {\n\tif talosConfigVersion != \"\" {\n\t\treturn fmt.Sprintf(`\nresource \"talos_machine_secrets\" \"this\" {\n\ttalos_version = \"%s\"\n}\n`, talosConfigVersion)\n\t}\n\n\treturn `\nresource \"talos_machine_secrets\" \"this\" {}\n`\n}\n"
  },
  {
    "path": "pkg/talos/testdata/patch-invalid.yaml",
    "content": "machine:\n  sysctl:\n    foo: bar\n"
  },
  {
    "path": "pkg/talos/testdata/patch-strategic.yaml",
    "content": "machine:\n  sysfs:\n    foo: bar\ncluster:\n  apiServer:\n    extraArgs:\n      foo: bar\n"
  },
  {
    "path": "pkg/talos/testdata/secrets.yaml",
    "content": "cluster:\n    id: _u8NZvwQ9ObtEN7iTzc-OEpk20K-rnO3FNcjvVEQ84Q=\n    secret: UnZE8oq6qPNI8tuw+WF3PGi2Zba0RQuit/aJTflOau8=\nsecrets:\n    bootstraptoken: m2wfba.pcyzhp6rf6pubqtk\n    secretboxencryptionsecret: avDR6jwn4iYS6sTOH689P2UcNUlh3UsuO+FaOKI2hls=\ntrustdinfo:\n    token: s5lcto.f2ythdlx6avcsny9\ncerts:\n    etcd:\n        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJmakNDQVNTZ0F3SUJBZ0lSQUt6KzNQbkZYWHNTdXNQb3RLTnVabG93Q2dZSUtvWkl6ajBFQXdJd0R6RU4KTUFzR0ExVUVDaE1FWlhSalpEQWVGdzB5TXpBME1ERXhORE01TURaYUZ3MHpNekF6TWpreE5ETTVNRFphTUE4eApEVEFMQmdOVkJBb1RCR1YwWTJRd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTbGFaU0p1UnhMCit4NDdYelY5OWIwaEd1dmdybGZrUnFEdStVUWlrSFJlRCtFL3VZUXprc1ArZTFLMVBUcFJVTG45ZEJYY21jd1AKazY2UXRCN09mQ0pEbzJFd1h6QU9CZ05WSFE4QkFmOEVCQU1DQW9Rd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSApBd0VHQ0NzR0FRVUZCd01DTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRk5kVHVVdmduZXcwCkJSa0dZRnJueWNpWFZjUTdNQW9HQ0NxR1NNNDlCQU1DQTBnQU1FVUNJUURJZGVqQ3ppL25xb3h0eUp3QnROTEYKTDE3UWdqQjNzMFoySUV5ZDZPTE51UUlnY0lHcWRWemJKQ3dXSkZXSWxnWWVyUGZvZzdzUjFxMWdKV25ST3p4UApBakE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\n        key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUoxWVI2ck9pd3N2TmRWZFErVnpiQ1hlRlBEbGJ1cDVUM1ZidnJrVDM2M1NvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFcFdtVWlia2NTL3NlTzE4MWZmVzlJUnJyNEs1WDVFYWc3dmxFSXBCMFhnL2hQN21FTTVMRAovbnRTdFQwNlVWQzUvWFFWM0puTUQ1T3VrTFFlem53aVF3PT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\n    k8s:\n        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJpakNDQVMrZ0F3SUJBZ0lRSE5COFFlVjRtazlUR3k4amtTUGtYVEFLQmdncWhrak9QUVFEQWpBVk1STXcKRVFZRFZRUUtFd3ByZFdKbGNtNWxkR1Z6TUI0WERUSXpNRFF3TVRFME16a3dObG9YRFRNek1ETXlPVEUwTXprdwpObG93RlRFVE1CRUdBMVVFQ2hNS2EzVmlaWEp1WlhSbGN6QlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VICkEwSUFCQVBKQjEwL3RnVFlkdVhrS0h6SVFEZDNLbW54MithbmFXcGN3RUlhWlhMbnNsRHRycGU3ancwaXRVK1oKa2w2eEd5STk4M0FpRkxWc004cHhra3RoZ2tTallUQmZNQTRHQTFVZER3RUIvd1FFQXdJQ2hEQWRCZ05WSFNVRQpGakFVQmdnckJnRUZCUWNEQVFZSUt3WUJCUVVIQXdJd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFCkZnUVU1K0hGd29PbTdURWhpcm1DTGt2SllyRmRQc293Q2dZSUtvWkl6ajBFQXdJRFNRQXdSZ0loQU1WZFNVUEUKcGlNWkpkNHNYV1pvdzdLb0djWWhPb1NtcDJkaUZEdUEzMjcyQWlFQTRuamcwN2ZhVEFGck1SUGF4SmFIMVhsdQpKTHBPMTh0bHZhVlVFMW5XY2xnPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\n        key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUZJQ0crOUR1Wm9YU0xiVjRWK1VoZkdRUWV5OUJ3dWEwZUx6M0hTU1hyMmhvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFQThrSFhUKzJCTmgyNWVRb2ZNaEFOM2NxYWZIYjVxZHBhbHpBUWhwbGN1ZXlVTzJ1bDd1UApEU0sxVDVtU1hyRWJJajN6Y0NJVXRXd3p5bkdTUzJHQ1JBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\n    k8saggregator:\n        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJZVENDQVFhZ0F3SUJBZ0lSQUtDY3hEVUM4UG9GK3pSajJWVlJLWTR3Q2dZSUtvWkl6ajBFQXdJd0FEQWUKRncweU16QTBNREV4TkRNNU1EWmFGdzB6TXpBek1qa3hORE01TURaYU1BQXdXVEFUQmdjcWhrak9QUUlCQmdncQpoa2pPUFFNQkJ3TkNBQVFPUjZKcTl1ekp3RWNFZnowc1dKdERVejhwNUpseHRJZkJjTTMzRFJ5cDhCSDZGQTFCCjJiUkx5ZTBsU3p6TXFmdVpFblhxOE9qazdobklGSUdsNlVNaW8yRXdYekFPQmdOVkhROEJBZjhFQkFNQ0FvUXcKSFFZRFZSMGxCQll3RkFZSUt3WUJCUVVIQXdFR0NDc0dBUVVGQndNQ01BOEdBMVVkRXdFQi93UUZNQU1CQWY4dwpIUVlEVlIwT0JCWUVGQUpPaUFGNTRhUXRPaUpzdFU2U2Z1QWpGOFJwTUFvR0NDcUdTTTQ5QkFNQ0Ewa0FNRVlDCklRREdPOUhXVXNaZlozRUdJTEdGRjJwUDIwUGNjSDZMV2hZSjg1eHB2RDBOSGdJaEFOOHFpVElXYVF2dUs3M1cKVENwT2g5TU1PS2o1YmFNcEh6M2FJOGVMZHBiVAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\n        key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU4rRDdGWGJoUTg4c1d6eEJPSXZtMVJVVVBtT25VeFBCRGlvR21mL1dnMjlvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFRGtlaWF2YnN5Y0JIQkg4OUxGaWJRMU0vS2VTWmNiU0h3WEROOXcwY3FmQVIraFFOUWRtMApTOG50SlVzOHpLbjdtUkoxNnZEbzVPNFp5QlNCcGVsRElnPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\n    k8sserviceaccount:\n        key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUVabmsrN2djSXBLdC8vM2lrQ1dLZm5SNnFjeWY5bHVyK1lGbzQyTlhVVVlvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFeG9rOTBEbnI2MGRYQ3BhQmxUMnVJUnRjdUJPLytCVjZEajVPaWYvTGVwSS95NktlQ2lRTApwRGZxenNHQW5zQXkrVHI3SWNxSUlROGZGaXRtK0t5emJBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\n    os:\n        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJQekNCOHFBREFnRUNBaEVBM0E0TEZ3cDVTZG5wTXVmYlp3NHVpekFGQmdNclpYQXdFREVPTUF3R0ExVUUKQ2hNRmRHRnNiM013SGhjTk1qTXdOREF4TVRRek9UQTJXaGNOTXpNd016STVNVFF6T1RBMldqQVFNUTR3REFZRApWUVFLRXdWMFlXeHZjekFxTUFVR0F5dGxjQU1oQUZ2TWUyeHFzSk9WemkvY0xLNXVXVzU2VmZZK29nWlYvQVowCmxlTFdtTWl1bzJFd1h6QU9CZ05WSFE4QkFmOEVCQU1DQW9Rd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSEF3RUcKQ0NzR0FRVUZCd01DTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRkxqK3VablllVFFUdEdmUgpOeVVQYWh6dzNkdkhNQVVHQXl0bGNBTkJBQVg4cVhJNm4ydlk3ZGxnZGtxckUvN25ua2kwTzFtVERDL3dBamlwCmpaemY5QmhocEdRUXFYSkxHdlhJTnRDaXN5KzQrcTVtOUVjUUpMMXF4UWdOdndnPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\n        key: LS0tLS1CRUdJTiBFRDI1NTE5IFBSSVZBVEUgS0VZLS0tLS0KTUM0Q0FRQXdCUVlESzJWd0JDSUVJSlVlQmxic3hhMW0vR1B0NTZCeVIvZ1Z3YWRzVmdkc3pXZEh4MWZiZ0c4VwotLS0tLUVORCBFRDI1NTE5IFBSSVZBVEUgS0VZLS0tLS0K\n"
  },
  {
    "path": "pkg/talos/testdata/secretsv1.2.yaml",
    "content": "cluster:\n    id: q_I385nl7MWqU1UpW224rQyZW4TWd_WmnxsA2MQLsl8=\n    secret: 1szT7qMuensSCcSVRtnFsG0pbXMLMSZ8r5wu/41aJBc=\nsecrets:\n    bootstraptoken: 5co9z6.qnnjtotc5ffntt62\n    aescbcencryptionsecret: hLrjDIpZ8gSGwejFfnUnjOrn9PQ7Bj3yq/ggAgD9AHA=\ntrustdinfo:\n    token: o2q4ek.ofdeihu3li44x7lr\ncerts:\n    etcd:\n        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJmakNDQVNTZ0F3SUJBZ0lSQU8rYmlXSlFJdHZXZUZ0UUNEVDhwRXd3Q2dZSUtvWkl6ajBFQXdJd0R6RU4KTUFzR0ExVUVDaE1FWlhSalpEQWVGdzB5TXpBME1ERXhOVFF4TURSYUZ3MHpNekF6TWpreE5UUXhNRFJhTUE4eApEVEFMQmdOVkJBb1RCR1YwWTJRd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFReHRnaFlZV1AvCngzWGFBM1RPVXd4Y1AySlh2QVYzdllaS2I1SENKK0E2M2dieE50dW5Gcm03NW8rK0ZQQndYdUtZUmMrU09pTXEKdWY5bjdkZmY4cUJKbzJFd1h6QU9CZ05WSFE4QkFmOEVCQU1DQW9Rd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSApBd0VHQ0NzR0FRVUZCd01DTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRkU2VUVneitoOSsvCnZYdnNod1d2bHJvQkh6SlFNQW9HQ0NxR1NNNDlCQU1DQTBnQU1FVUNJUUQ3YTFzMy91cmRybFlxaXJxTmN6aTIKTm5qNVFCdFVmczFNYkNqNTdkYXR3d0lnZlJYdEIyWVZMUy9OMFVQTDkxekhITCtLM09EaEZ2M1dsc0gwMlpmdgpMNHc9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K\n        key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUJDNUpZQmgzWWQ2NnJwWkcvTHZEMWt4SFRvWTA4QnZsQkpMcy9aZXR4NldvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFTWJZSVdHRmovOGQxMmdOMHpsTU1YRDlpVjd3RmQ3MkdTbStSd2lmZ090NEc4VGJicHhhNQp1K2FQdmhUd2NGN2ltRVhQa2pvaktybi9aKzNYMy9LZ1NRPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\n    k8s:\n        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJpVENDQVMrZ0F3SUJBZ0lRVW9hWGkyZGxUWHk1alNBUVdvSUZOVEFLQmdncWhrak9QUVFEQWpBVk1STXcKRVFZRFZRUUtFd3ByZFdKbGNtNWxkR1Z6TUI0WERUSXpNRFF3TVRFMU5ERXdORm9YRFRNek1ETXlPVEUxTkRFdwpORm93RlRFVE1CRUdBMVVFQ2hNS2EzVmlaWEp1WlhSbGN6QlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VICkEwSUFCRWJieTQreTdIWmZUcVNNaDRtMWx3a3E3THE5WUtWdVhmV3BJLzZ4K1orZC9uUFJFNFA0eGhNUklKL3oKZHl4TDJxTGNSOUcxV3pjVWJBRVYrMjliUWNDallUQmZNQTRHQTFVZER3RUIvd1FFQXdJQ2hEQWRCZ05WSFNVRQpGakFVQmdnckJnRUZCUWNEQVFZSUt3WUJCUVVIQXdJd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFCkZnUVUzRG8xb2MzM054dWhYRTJ4M2NvbHM3a2dWWmN3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUloQU9pb3RHR1MKNnJLdWFoT2twMlQ5NjRzSUhhdmx3bUJqZ0ljVkI1dTFPV2RsQWlBRXZKUUVTRGNBZWlmVm1seG1pdWVDMHl4SQowODBqY2FxUjdUVWNjaHhrSnc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\n        key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUx5bm9FaURjeG1NL3ZlL1B1R0YwWFNjeEgydG10SGZSdVU0SkVvejBGRmtvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFUnR2TGo3THNkbDlPcEl5SGliV1hDU3JzdXIxZ3BXNWQ5YWtqL3JINW41MytjOUVUZy9qRwpFeEVnbi9OM0xFdmFvdHhIMGJWYk54UnNBUlg3YjF0QndBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\n    k8saggregator:\n        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJZRENDQVFhZ0F3SUJBZ0lSQUp5THJmLzk5aE00a1ZNWTJraFd4TjR3Q2dZSUtvWkl6ajBFQXdJd0FEQWUKRncweU16QTBNREV4TlRReE1EUmFGdzB6TXpBek1qa3hOVFF4TURSYU1BQXdXVEFUQmdjcWhrak9QUUlCQmdncQpoa2pPUFFNQkJ3TkNBQVFZTTBWWUVZWTVOaURlNHp6Z21mYlJSdDRNalRmOUlyeUVVcms1SjNPRFQzYkFpanVDCmd6eWpmTkZIbFlXbm9PcWZBeGpjVVVsQkU2L2xuRmdiMzNwUW8yRXdYekFPQmdOVkhROEJBZjhFQkFNQ0FvUXcKSFFZRFZSMGxCQll3RkFZSUt3WUJCUVVIQXdFR0NDc0dBUVVGQndNQ01BOEdBMVVkRXdFQi93UUZNQU1CQWY4dwpIUVlEVlIwT0JCWUVGTHBKUEhhRGw1UjY4NjlDNEVyVXF5WHhBeUpWTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDCklFc0VlOElSNEwvK3phMC9CbzlUNGRKbERpQ3VDK1BSd1JueXE4OEE5dFUvQWlFQTBGUXNJcGk5V1ZiU2krODQKQkVCaGRWTkpmQUVUYTZVQ2UrTWFsNUJRUjlrPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\n        key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUMxSDViQUY5RkJWQzVIQjZ2dzJwL1FRUFkvWEVjdzhaTUJ0ZDZFTmw3cXFvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFR0RORldCR0dPVFlnM3VNODRKbjIwVWJlREkwMy9TSzhoRks1T1NkemcwOTJ3SW83Z29NOApvM3pSUjVXRnA2RHFud01ZM0ZGSlFST3Y1WnhZRzk5NlVBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\n    k8sserviceaccount:\n        key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUxHRjlhcmp4SEdyMExMbTdMTjg0Ympjbml2RWpGSkxlUFNvVGhZUS9maWdvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFNjRuQVlld3hqeVkrVkY4MDZ5WU5iU3pnNEl4cFh6TW1hMW93b3FjbDc5elZtMkRsbHcxUApYR3FTZ0hpWUxwcjZ1ZU5OeSswcXdOdklCU3RKSXZLVzNnPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=\n    os:\n        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJQakNCOGFBREFnRUNBaEIzcXY0bDNhTStSaGFsWmdHOGowdDNNQVVHQXl0bGNEQVFNUTR3REFZRFZRUUsKRXdWMFlXeHZjekFlRncweU16QTBNREV4TlRReE1EUmFGdzB6TXpBek1qa3hOVFF4TURSYU1CQXhEakFNQmdOVgpCQW9UQlhSaGJHOXpNQ293QlFZREsyVndBeUVBWk1TT1d4aHF4UThEbHdUVmszM2xRN09ydDAvOTE5b0JXTVpUCmRSU3Q4SGFqWVRCZk1BNEdBMVVkRHdFQi93UUVBd0lDaERBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFRWUkKS3dZQkJRVUhBd0l3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVYkhDeHcyOTd4RHc3Tjh0SQpDQTJTUDc2K3Q5OHdCUVlESzJWd0EwRUFrcnQ1UEVnZ2JZNFFlYnNIa2lDTmZlMFpZNlE1UmZhVm52TVRxOE1lCnRhSktTQ1NPYTljczh2dXVDMnl2QmNSU0hPWldocG9WaW05bXhEaVc3TDZTQXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==\n        key: LS0tLS1CRUdJTiBFRDI1NTE5IFBSSVZBVEUgS0VZLS0tLS0KTUM0Q0FRQXdCUVlESzJWd0JDSUVJRjdtNmJKWHNOd3F4ejFMaXRnVlFJSEx5WDJab1hadW85UTNEZjRGSThWaAotLS0tLUVORCBFRDI1NTE5IFBSSVZBVEUgS0VZLS0tLS0K\n"
  },
  {
    "path": "pkg/talos/util.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\npackage talos\n\nimport (\n\t\"context\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/elliptic\"\n\t\"crypto/sha256\"\n\t\"crypto/tls\"\n\tstdlibx509 \"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/base64\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/hashicorp/terraform-plugin-framework/schema/validator\"\n\t\"github.com/hashicorp/terraform-plugin-framework/types\"\n\t\"github.com/siderolabs/crypto/x509\"\n\tsideronet \"github.com/siderolabs/net\"\n\t\"github.com/siderolabs/talos/pkg/machinery/client\"\n\tclientconfig \"github.com/siderolabs/talos/pkg/machinery/client/config\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/bundle\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/configpatcher\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/encoder\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/generate\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/generate/secrets\"\n\t\"github.com/siderolabs/talos/pkg/machinery/config/machine\"\n\t\"github.com/siderolabs/talos/pkg/machinery/constants\"\n\t\"github.com/siderolabs/talos/pkg/machinery/gendata\"\n\t\"github.com/siderolabs/talos/pkg/machinery/role\"\n\t\"golang.org/x/crypto/hkdf\"\n)\n\ntype machineConfigGenerateOptions struct { //nolint:govet\n\tmachineType       machine.Type\n\tclusterName       string\n\tclusterEndpoint   string\n\tmachineSecrets    *secrets.Bundle\n\tkubernetesVersion string\n\ttalosVersion      string\n\tdocsEnabled       bool\n\texamplesEnabled   bool\n\tconfigPatches     []string\n}\n\nfunc (m *machineConfigGenerateOptions) generate() (string, error) {\n\tgenOptions := make([]generate.Option, 0)\n\n\t// default gen options\n\tgenOptions = append(genOptions,\n\t\tgenerate.WithClusterDiscovery(true),\n\t\tgenerate.WithDNSDomain(constants.DefaultDNSDomain),\n\t\tgenerate.WithInstallDisk(\"/dev/sda\"),\n\t\tgenerate.WithInstallImage(GenerateInstallerImage()),\n\t\tgenerate.WithSecretsBundle(m.machineSecrets),\n\t)\n\n\tversionContract, err := validateVersionContract(m.talosVersion)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tgenOptions = append(genOptions, generate.WithVersionContract(versionContract))\n\n\tcommentsFlags := encoder.CommentsDisabled\n\n\tif m.docsEnabled {\n\t\tcommentsFlags |= encoder.CommentsDocs\n\t}\n\n\tif m.examplesEnabled {\n\t\tcommentsFlags |= encoder.CommentsExamples\n\t}\n\n\tconfigBundleOpts := []bundle.Option{\n\t\tbundle.WithInputOptions(\n\t\t\t&bundle.InputOptions{\n\t\t\t\tClusterName: m.clusterName,\n\t\t\t\tEndpoint:    m.clusterEndpoint,\n\t\t\t\tKubeVersion: strings.TrimPrefix(m.kubernetesVersion, \"v\"),\n\t\t\t\tGenOptions:  genOptions,\n\t\t\t},\n\t\t),\n\t\tbundle.WithVerbose(false),\n\t}\n\n\taddConfigPatch := func(configPatches []string, configOpt func([]configpatcher.Patch) bundle.Option) error {\n\t\tvar patches []configpatcher.Patch\n\n\t\tpatches, err = configpatcher.LoadPatches(configPatches)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error parsing config patch: %w\", err)\n\t\t}\n\n\t\tconfigBundleOpts = append(configBundleOpts, configOpt(patches))\n\n\t\treturn nil\n\t}\n\n\tswitch m.machineType { //nolint:exhaustive\n\tcase machine.TypeControlPlane:\n\t\tif err = addConfigPatch(m.configPatches, bundle.WithPatchControlPlane); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\tcase machine.TypeWorker:\n\t\tif err = addConfigPatch(m.configPatches, bundle.WithPatchWorker); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t}\n\n\tconfigBundle, err := bundle.NewBundle(configBundleOpts...)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tmachineConfigBytes, err := configBundle.Serialize(commentsFlags, m.machineType)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn string(machineConfigBytes), nil\n}\n\n// GenerateInstallerImage generates the installer image name.\nfunc GenerateInstallerImage() string {\n\treturn fmt.Sprintf(\"%s/%s/installer:%s\", gendata.ImagesRegistry, gendata.ImagesUsername, gendata.VersionTag)\n}\n\nfunc secretsBundleTomachineSecrets(secretsBundle *secrets.Bundle) (talosMachineSecretsResourceModelV1, error) {\n\tmodel := talosMachineSecretsResourceModelV1{\n\t\tID: types.StringValue(\"machine_secrets\"),\n\t\tMachineSecrets: machineSecrets{\n\t\t\tCluster: machineSecretsCluster{\n\t\t\t\tID:     types.StringValue(secretsBundle.Cluster.ID),\n\t\t\t\tSecret: types.StringValue(secretsBundle.Cluster.Secret),\n\t\t\t},\n\t\t\tSecrets: machineSecretsSecrets{\n\t\t\t\tBootstrapToken:            types.StringValue(secretsBundle.Secrets.BootstrapToken),\n\t\t\t\tSecretboxEncryptionSecret: types.StringValue(secretsBundle.Secrets.SecretboxEncryptionSecret),\n\t\t\t},\n\t\t\tTrustdInfo: machineSecretsTrustdInfo{\n\t\t\t\tToken: types.StringValue(secretsBundle.TrustdInfo.Token),\n\t\t\t},\n\t\t\tCerts: machineSecretsCerts{\n\t\t\t\tEtcd: machineSecretsCertKeyPair{\n\t\t\t\t\tCert: types.StringValue(bytesToBase64(secretsBundle.Certs.Etcd.Crt)),\n\t\t\t\t\tKey:  types.StringValue(bytesToBase64(secretsBundle.Certs.Etcd.Key)),\n\t\t\t\t},\n\t\t\t\tK8s: machineSecretsCertKeyPair{\n\t\t\t\t\tCert: types.StringValue(bytesToBase64(secretsBundle.Certs.K8s.Crt)),\n\t\t\t\t\tKey:  types.StringValue(bytesToBase64(secretsBundle.Certs.K8s.Key)),\n\t\t\t\t},\n\t\t\t\tK8sServiceAccount: machineSecretsCertsK8sServiceAccount{\n\t\t\t\t\tKey: types.StringValue(bytesToBase64(secretsBundle.Certs.K8sServiceAccount.Key)),\n\t\t\t\t},\n\t\t\t\tOS: machineSecretsCertKeyPair{\n\t\t\t\t\tCert: types.StringValue(bytesToBase64(secretsBundle.Certs.OS.Crt)),\n\t\t\t\t\tKey:  types.StringValue(bytesToBase64(secretsBundle.Certs.OS.Key)),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tif secretsBundle.Certs.K8sAggregator.Crt != nil {\n\t\tmodel.MachineSecrets.Certs.K8sAggregator.Cert = types.StringValue(bytesToBase64(secretsBundle.Certs.K8sAggregator.Crt))\n\t\tmodel.MachineSecrets.Certs.K8sAggregator.Key = types.StringValue(bytesToBase64(secretsBundle.Certs.K8sAggregator.Key))\n\t}\n\n\t// support for talos < 1.3\n\tif secretsBundle.Secrets.AESCBCEncryptionSecret != \"\" {\n\t\tmodel.MachineSecrets.Secrets.AESCBCEncryptionSecret = types.StringValue(secretsBundle.Secrets.AESCBCEncryptionSecret)\n\t}\n\n\tcc, err := generateClientConfigurationWithTTL(secretsBundle, constants.TalosAPIDefaultCertificateValidityDuration)\n\tif err != nil {\n\t\treturn model, err\n\t}\n\n\tmodel.ClientConfiguration = cc\n\n\treturn model, nil\n}\n\n// generateClientConfigurationWithTTL generates a clientConfiguration with a TTL-based cert.\n// Used by the managed talos_machine_secrets resource which stores and renews certs in state.\nfunc generateClientConfigurationWithTTL(secretsBundle *secrets.Bundle, ttl time.Duration) (clientConfiguration, error) {\n\tif secretsBundle.Clock == nil {\n\t\tsecretsBundle.Clock = secrets.NewFixedClock(time.Now())\n\t}\n\n\tclientcert, err := secretsBundle.GenerateTalosAPIClientCertificateWithTTL(role.MakeSet(role.Admin), ttl)\n\tif err != nil {\n\t\treturn clientConfiguration{}, err\n\t}\n\n\treturn clientConfiguration{\n\t\tCA:   types.StringValue(bytesToBase64(secretsBundle.Certs.OS.Crt)),\n\t\tCert: types.StringValue(bytesToBase64(clientcert.Crt)),\n\t\tKey:  types.StringValue(bytesToBase64(clientcert.Key)),\n\t}, nil\n}\n\n// generateClientConfiguration generates a clientConfiguration from a secrets bundle.\n//\n// The admin client certificate and key are derived deterministically using HKDF\n// (RFC 5869) seeded from the OS CA private key and all cert-relevant inputs.\n// Same inputs always produce byte-identical output — no crypto/rand is used.\n//\n// Supports Ed25519 and ECDSA P-256 OS CA keys (Talos uses Ed25519 since v1.x).\n// Ed25519 signing is deterministic by design (RFC 8032); ECDSA uses RFC 6979.\nfunc generateClientConfiguration(secretsBundle *secrets.Bundle, clusterName string, notBefore, notAfter time.Time) (clientConfiguration, error) {\n\tcaCertBlock, _ := pem.Decode(secretsBundle.Certs.OS.Crt)\n\tif caCertBlock == nil {\n\t\treturn clientConfiguration{}, fmt.Errorf(\"error decoding OS CA certificate PEM\")\n\t}\n\n\tcaCert, err := stdlibx509.ParseCertificate(caCertBlock.Bytes)\n\tif err != nil {\n\t\treturn clientConfiguration{}, fmt.Errorf(\"error parsing OS CA certificate: %w\", err)\n\t}\n\n\tcaKeyBlock, _ := pem.Decode(secretsBundle.Certs.OS.Key)\n\tif caKeyBlock == nil {\n\t\treturn clientConfiguration{}, fmt.Errorf(\"error decoding OS CA private key PEM\")\n\t}\n\n\tinfo := fmt.Sprintf(\"talos-clientconfig:v1:%s:%d:%d\", clusterName, notBefore.Unix(), notAfter.Unix())\n\tdeterministicReader := hkdf.New(sha256.New, secretsBundle.Certs.OS.Key, []byte(\"talos-clientconfig-v1\"), []byte(info))\n\n\tserialBytes := make([]byte, 16)\n\tif _, err = deterministicReader.Read(serialBytes); err != nil {\n\t\treturn clientConfiguration{}, fmt.Errorf(\"error deriving serial number: %w\", err)\n\t}\n\n\ttemplate := &stdlibx509.Certificate{\n\t\tSerialNumber: new(big.Int).SetBytes(serialBytes),\n\t\tSubject: pkix.Name{\n\t\t\tOrganization: []string{\"os:admin\"},\n\t\t},\n\t\tNotBefore:   notBefore,\n\t\tNotAfter:    notAfter,\n\t\tKeyUsage:    stdlibx509.KeyUsageDigitalSignature,\n\t\tExtKeyUsage: []stdlibx509.ExtKeyUsage{stdlibx509.ExtKeyUsageClientAuth},\n\t}\n\n\tvar (\n\t\tcertDER      []byte\n\t\tclientKeyPEM []byte\n\t)\n\n\tcaKeyParsed, parseErr := parseCAPrivateKey(caKeyBlock)\n\tif parseErr != nil {\n\t\treturn clientConfiguration{}, parseErr\n\t}\n\n\tswitch caKey := caKeyParsed.(type) {\n\tcase ed25519.PrivateKey:\n\t\tadminKeyBytes := make([]byte, ed25519.SeedSize)\n\t\tif _, err = deterministicReader.Read(adminKeyBytes); err != nil {\n\t\t\treturn clientConfiguration{}, fmt.Errorf(\"error deriving admin key bytes: %w\", err)\n\t\t}\n\n\t\tadminKey := ed25519.NewKeyFromSeed(adminKeyBytes)\n\n\t\t// Ed25519 signing is deterministic per RFC 8032 — rand reader is unused.\n\t\tcertDER, err = stdlibx509.CreateCertificate(nil, template, caCert, adminKey.Public(), caKey)\n\t\tif err != nil {\n\t\t\treturn clientConfiguration{}, fmt.Errorf(\"error signing admin certificate: %w\", err)\n\t\t}\n\n\t\tadminKeyDER, marshalErr := stdlibx509.MarshalPKCS8PrivateKey(adminKey)\n\t\tif marshalErr != nil {\n\t\t\treturn clientConfiguration{}, fmt.Errorf(\"error marshaling admin private key: %w\", marshalErr)\n\t\t}\n\n\t\tclientKeyPEM = pem.EncodeToMemory(&pem.Block{Type: \"PRIVATE KEY\", Bytes: adminKeyDER})\n\n\tcase *ecdsa.PrivateKey:\n\t\tadminKeyBytes := make([]byte, 32)\n\t\tif _, err = deterministicReader.Read(adminKeyBytes); err != nil {\n\t\t\treturn clientConfiguration{}, fmt.Errorf(\"error deriving admin key bytes: %w\", err)\n\t\t}\n\n\t\tadminKey, ecParseErr := ecdsa.ParseRawPrivateKey(elliptic.P256(), adminKeyBytes)\n\t\tif ecParseErr != nil {\n\t\t\treturn clientConfiguration{}, fmt.Errorf(\"error parsing derived admin key: %w\", ecParseErr)\n\t\t}\n\n\t\tcaSigner := &deterministicECDSASigner{key: caKey}\n\n\t\tcertDER, err = stdlibx509.CreateCertificate(nil, template, caCert, &adminKey.PublicKey, caSigner)\n\t\tif err != nil {\n\t\t\treturn clientConfiguration{}, fmt.Errorf(\"error signing admin certificate: %w\", err)\n\t\t}\n\n\t\tadminKeyDER, marshalErr := stdlibx509.MarshalECPrivateKey(adminKey)\n\t\tif marshalErr != nil {\n\t\t\treturn clientConfiguration{}, fmt.Errorf(\"error marshaling admin private key: %w\", marshalErr)\n\t\t}\n\n\t\tclientKeyPEM = pem.EncodeToMemory(&pem.Block{Type: \"EC PRIVATE KEY\", Bytes: adminKeyDER})\n\n\tdefault:\n\t\treturn clientConfiguration{}, fmt.Errorf(\"unsupported OS CA private key type: %T\", caKeyParsed)\n\t}\n\n\tclientCertPEM := pem.EncodeToMemory(&pem.Block{Type: \"CERTIFICATE\", Bytes: certDER})\n\n\treturn clientConfiguration{\n\t\tCA:   types.StringValue(bytesToBase64(secretsBundle.Certs.OS.Crt)),\n\t\tCert: types.StringValue(bytesToBase64(clientCertPEM)),\n\t\tKey:  types.StringValue(bytesToBase64(clientKeyPEM)),\n\t}, nil\n}\n\n// parseCAPrivateKey parses a PEM block into either an ed25519.PrivateKey or *ecdsa.PrivateKey.\nfunc parseCAPrivateKey(block *pem.Block) (any, error) {\n\tswitch block.Type {\n\tcase \"EC PRIVATE KEY\":\n\t\tkey, err := stdlibx509.ParseECPrivateKey(block.Bytes)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error parsing OS CA private key: %w\", err)\n\t\t}\n\n\t\treturn key, nil\n\n\tcase \"ED25519 PRIVATE KEY\", \"PRIVATE KEY\":\n\t\tparsed, err := stdlibx509.ParsePKCS8PrivateKey(block.Bytes)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error parsing OS CA private key: %w\", err)\n\t\t}\n\n\t\tswitch k := parsed.(type) {\n\t\tcase ed25519.PrivateKey:\n\t\t\treturn k, nil\n\t\tcase *ecdsa.PrivateKey:\n\t\t\treturn k, nil\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unsupported OS CA private key type in PKCS#8: %T\", parsed)\n\t\t}\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported OS CA private key PEM type: %s\", block.Type)\n\t}\n}\n\ntype clientConfigTimestampError struct {\n\tsummary string\n\tdetail  string\n}\n\nfunc (e *clientConfigTimestampError) Error() string { return e.detail }\n\n// resolveClientConfigTimestamps resolves notBefore/notAfter for the admin client certificate.\n// When notBeforeStr is non-empty it parses the RFC3339 timestamp and adds crtTTLStr (default 87600h).\n// When notBeforeStr is empty it reads the timestamps from the OS CA PEM.\nfunc resolveClientConfigTimestamps(notBeforeStr, crtTTLStr string, osCACert []byte) (notBefore, notAfter time.Time, tsErr *clientConfigTimestampError) {\n\tif notBeforeStr != \"\" {\n\t\tvar err error\n\n\t\tnotBefore, err = time.Parse(time.RFC3339, notBeforeStr)\n\t\tif err != nil {\n\t\t\treturn time.Time{}, time.Time{}, &clientConfigTimestampError{\n\t\t\t\tsummary: \"invalid not_before\",\n\t\t\t\tdetail:  fmt.Sprintf(\"unable to parse not_before %q as RFC3339: %s\", notBeforeStr, err.Error()),\n\t\t\t}\n\t\t}\n\n\t\tcrtTTL := 87600 * time.Hour\n\n\t\tif crtTTLStr != \"\" {\n\t\t\tcrtTTL, err = time.ParseDuration(crtTTLStr)\n\t\t\tif err != nil {\n\t\t\t\treturn time.Time{}, time.Time{}, &clientConfigTimestampError{\n\t\t\t\t\tsummary: \"invalid crt_ttl\",\n\t\t\t\t\tdetail:  fmt.Sprintf(\"unable to parse crt_ttl %q: %s\", crtTTLStr, err.Error()),\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn notBefore, notBefore.Add(crtTTL), nil\n\t}\n\n\tblock, _ := pem.Decode(osCACert)\n\tif block == nil {\n\t\treturn time.Time{}, time.Time{}, &clientConfigTimestampError{\n\t\t\tsummary: \"failed to parse Talos OS CA certificate\",\n\t\t\tdetail:  \"PEM block is nil\",\n\t\t}\n\t}\n\n\tcaCert, err := stdlibx509.ParseCertificate(block.Bytes)\n\tif err != nil {\n\t\treturn time.Time{}, time.Time{}, &clientConfigTimestampError{\n\t\t\tsummary: \"failed to parse Talos OS CA certificate\",\n\t\t\tdetail:  err.Error(),\n\t\t}\n\t}\n\n\treturn caCert.NotBefore, caCert.NotAfter, nil\n}\n\nfunc machineSecretsToSecretsBundle(model talosMachineSecretsResourceModelV1) (*secrets.Bundle, error) {\n\tsecretsBundle := &secrets.Bundle{\n\t\tCluster: &secrets.Cluster{\n\t\t\tID:     model.MachineSecrets.Cluster.ID.ValueString(),\n\t\t\tSecret: model.MachineSecrets.Cluster.Secret.ValueString(),\n\t\t},\n\t\tSecrets: &secrets.Secrets{\n\t\t\tBootstrapToken:            model.MachineSecrets.Secrets.BootstrapToken.ValueString(),\n\t\t\tSecretboxEncryptionSecret: model.MachineSecrets.Secrets.SecretboxEncryptionSecret.ValueString(),\n\t\t},\n\t\tTrustdInfo: &secrets.TrustdInfo{\n\t\t\tToken: model.MachineSecrets.TrustdInfo.Token.ValueString(),\n\t\t},\n\t}\n\n\tif model.MachineSecrets.Secrets.AESCBCEncryptionSecret.ValueString() != \"\" {\n\t\tsecretsBundle.Secrets.AESCBCEncryptionSecret = model.MachineSecrets.Secrets.AESCBCEncryptionSecret.ValueString()\n\t}\n\n\tetcdCert, err := base64ToBytes(model.MachineSecrets.Certs.Etcd.Cert.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tetcdKey, err := base64ToBytes(model.MachineSecrets.Certs.Etcd.Key.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tk8sCert, err := base64ToBytes(model.MachineSecrets.Certs.K8s.Cert.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tk8sKey, err := base64ToBytes(model.MachineSecrets.Certs.K8s.Key.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tk8sAggregatorCert, err := base64ToBytes(model.MachineSecrets.Certs.K8sAggregator.Cert.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tk8sAggregatorKey, err := base64ToBytes(model.MachineSecrets.Certs.K8sAggregator.Key.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tk8sServiceAccountKey, err := base64ToBytes(model.MachineSecrets.Certs.K8sServiceAccount.Key.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tosCert, err := base64ToBytes(model.MachineSecrets.Certs.OS.Cert.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tosKey, err := base64ToBytes(model.MachineSecrets.Certs.OS.Key.ValueString())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsecretsBundle.Certs = &secrets.Certs{\n\t\tEtcd: &x509.PEMEncodedCertificateAndKey{\n\t\t\tCrt: etcdCert,\n\t\t\tKey: etcdKey,\n\t\t},\n\t\tK8s: &x509.PEMEncodedCertificateAndKey{\n\t\t\tCrt: k8sCert,\n\t\t\tKey: k8sKey,\n\t\t},\n\t\tK8sAggregator: &x509.PEMEncodedCertificateAndKey{\n\t\t\tCrt: k8sAggregatorCert,\n\t\t\tKey: k8sAggregatorKey,\n\t\t},\n\t\tK8sServiceAccount: &x509.PEMEncodedKey{\n\t\t\tKey: k8sServiceAccountKey,\n\t\t},\n\t\tOS: &x509.PEMEncodedCertificateAndKey{\n\t\t\tCrt: osCert,\n\t\t\tKey: osKey,\n\t\t},\n\t}\n\n\treturn secretsBundle, nil\n}\n\nfunc validateVersionContract(version string) (*config.VersionContract, error) {\n\tversionContract, err := config.ParseContractFromVersion(version)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn versionContract, nil\n}\n\nfunc talosClientOp(ctx context.Context, endpoint, node string, tc *clientconfig.Config, opFunc func(ctx context.Context, c *client.Client) error) error {\n\tnodeCtx := client.WithNode(ctx, node)\n\n\tc, err := client.New(ctx, client.WithTLSConfig(&tls.Config{\n\t\tInsecureSkipVerify: true,\n\t}), client.WithEndpoints(endpoint))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = c.Disks(nodeCtx)\n\tif err != nil {\n\t\tc.Close() //nolint:errcheck\n\n\t\tc, err = client.New(ctx, client.WithConfig(tc), client.WithEndpoints(endpoint))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tdefer c.Close() //nolint:errcheck\n\n\treturn opFunc(nodeCtx, c)\n}\n\ntype talosVersionValidator struct{}\n\nfunc talosVersionValid() talosVersionValidator {\n\treturn talosVersionValidator{}\n}\n\nfunc (v talosVersionValidator) ValidateString(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) {\n\tif req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {\n\t\treturn\n\t}\n\n\tversion := req.ConfigValue.ValueString()\n\n\t_, err := validateVersionContract(version)\n\tif err != nil {\n\t\tresp.Diagnostics.AddError(\"Invalid version\", err.Error())\n\t}\n}\n\nfunc (v talosVersionValidator) Description(_ context.Context) string {\n\treturn \"Validates that the talos version is valid\"\n}\n\nfunc (v talosVersionValidator) MarkdownDescription(ctx context.Context) string {\n\treturn v.Description(ctx)\n}\n\ntype goDurationValidator struct{}\n\nfunc goDurationValid() goDurationValidator {\n\treturn goDurationValidator{}\n}\n\nfunc (v goDurationValidator) ValidateString(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) {\n\tif req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {\n\t\treturn\n\t}\n\n\tif _, err := time.ParseDuration(req.ConfigValue.ValueString()); err != nil {\n\t\tresp.Diagnostics.AddAttributeError(\n\t\t\treq.Path,\n\t\t\t\"invalid crt_ttl\",\n\t\t\tfmt.Sprintf(\"unable to parse duration %q: %s\", req.ConfigValue.ValueString(), err.Error()),\n\t\t)\n\t}\n}\n\nfunc (v goDurationValidator) Description(_ context.Context) string {\n\treturn \"Validates that the value is a valid Go duration string (e.g. \\\"8760h\\\", \\\"87600h\\\")\"\n}\n\nfunc (v goDurationValidator) MarkdownDescription(ctx context.Context) string {\n\treturn v.Description(ctx)\n}\n\ntype rfc3339Validator struct{}\n\nfunc rfc3339Valid() rfc3339Validator {\n\treturn rfc3339Validator{}\n}\n\nfunc (v rfc3339Validator) ValidateString(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) {\n\tif req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {\n\t\treturn\n\t}\n\n\tif _, err := time.Parse(time.RFC3339, req.ConfigValue.ValueString()); err != nil {\n\t\tresp.Diagnostics.AddAttributeError(\n\t\t\treq.Path,\n\t\t\t\"invalid not_before\",\n\t\t\tfmt.Sprintf(\"unable to parse not_before %q as RFC3339: %s\", req.ConfigValue.ValueString(), err.Error()),\n\t\t)\n\t}\n}\n\nfunc (v rfc3339Validator) Description(_ context.Context) string {\n\treturn \"must be a valid RFC3339 timestamp (e.g. \\\"2024-01-01T00:00:00Z\\\")\"\n}\n\nfunc (v rfc3339Validator) MarkdownDescription(ctx context.Context) string {\n\treturn v.Description(ctx)\n}\n\nfunc validateClusterEndpoint(endpoint string) error {\n\t// Validate url input to ensure it has https:// scheme before we attempt to gen\n\tu, err := url.Parse(endpoint)\n\tif err != nil {\n\t\tif !strings.Contains(endpoint, \"/\") {\n\t\t\t// not a URL, could be just host:port\n\t\t\tu = &url.URL{\n\t\t\t\tHost: endpoint,\n\t\t\t}\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"failed to parse the cluster endpoint URL: %w\", err)\n\t\t}\n\t}\n\n\tif u.Scheme == \"\" {\n\t\tif u.Port() == \"\" {\n\t\t\treturn fmt.Errorf(\"no scheme and port specified for the cluster endpoint URL\\ntry: %q\", fixControlPlaneEndpoint(u))\n\t\t}\n\n\t\treturn fmt.Errorf(\"no scheme specified for the cluster endpoint URL\\ntry: %q\", fixControlPlaneEndpoint(u))\n\t}\n\n\tif u.Scheme != \"https\" {\n\t\treturn fmt.Errorf(\"the control plane endpoint URL should have scheme https://\\ntry: %q\", fixControlPlaneEndpoint(u))\n\t}\n\n\tif err = sideronet.ValidateEndpointURI(endpoint); err != nil {\n\t\treturn fmt.Errorf(\"error validating the cluster endpoint URL: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc fixControlPlaneEndpoint(u *url.URL) *url.URL {\n\t// handle the case when the hostname/IP is given without the port, it parses as URL Path\n\tif u.Scheme == \"\" && u.Host == \"\" && u.Path != \"\" {\n\t\tu.Host = u.Path\n\t\tu.Path = \"\"\n\t}\n\n\tu.Scheme = \"https\"\n\n\tif u.Port() == \"\" {\n\t\tu.Host = fmt.Sprintf(\"%s:%d\", u.Host, constants.DefaultControlPlanePort)\n\t}\n\n\treturn u\n}\n\nfunc bytesToBase64(b []byte) string {\n\treturn base64.StdEncoding.EncodeToString(b)\n}\n\nfunc base64ToBytes(in string) ([]byte, error) {\n\treturn base64.StdEncoding.DecodeString(in)\n}\n\nfunc talosClientTFConfigToTalosClientConfig(clusterName, ca, cert, key string) (*clientconfig.Config, error) {\n\tcaCert, err := base64ToBytes(ca)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tclientCert, err := base64ToBytes(cert)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tclientKey, err := base64ToBytes(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttalosConfig := clientconfig.NewConfig(\n\t\tclusterName,\n\t\tnil,\n\t\tcaCert,\n\t\t&x509.PEMEncodedCertificateAndKey{\n\t\t\tCrt: clientCert,\n\t\t\tKey: clientKey,\n\t\t},\n\t)\n\n\treturn talosConfig, nil\n}\n"
  },
  {
    "path": "templates/data-sources/machine_configuration.md.tmpl",
    "content": "---\npage_title: \"{{.Name}} {{.Type}} - {{.RenderedProviderName}}\"\nsubcategory: \"\"\ndescription: |-\n{{ .Description | plainmarkdown | trimspace | prefixlines \"  \" }}\n---\n\n# {{.Name}} ({{.Type}})\n\n{{ .Description | trimspace }}\n\n-> **Note:** It is recommended to set the optional `talos_version` attribute. Otherwise when using a new version of the provider with a new major version of the Talos SDK, new machineconfig features will be enabled by default which could cause unexpected behavior.\n\n{{ if .HasExample -}}\n## Example Usage\n\n{{ tffile (printf .ExampleFile) }}\n{{- end }}\n{{ .SchemaMarkdown | trimspace }}\n"
  },
  {
    "path": "templates/data-sources/machine_disks.md.tmpl",
    "content": "---\npage_title: \"{{.Name}} {{.Type}} - {{.RenderedProviderName}}\"\nsubcategory: \"\"\ndescription: |-\n{{ .Description | plainmarkdown | trimspace | prefixlines \"  \" }}\n---\n\n# {{.Name}} ({{.Type}})\n\n{{ .Description | trimspace }}\n\n-> **Note:** Since Talos natively supports `.machine.install.diskSelector`, the `talos_machine_disks` data source maybe just used to query disk information that could be used elsewhere. It's recommended to use `machine.install.diskSelector` in Talos machine configuration.\n\n{{ if .HasExample -}}\n## Example Usage\n\n{{ tffile (printf .ExampleFile) }}\n{{- end }}\n{{ .SchemaMarkdown | trimspace }}\n"
  },
  {
    "path": "templates/ephemeral-resources/machine_configuration.md.tmpl",
    "content": "---\npage_title: \"{{.Name}} {{.Type}} - {{.RenderedProviderName}}\"\nsubcategory: \"\"\ndescription: |-\n{{ .Description | plainmarkdown | trimspace | prefixlines \"  \" }}\n---\n\n# {{.Name}} ({{.Type}})\n\n{{ .Description | trimspace }}\n\n-> **Note:** It is recommended to set the optional `talos_version` attribute. Otherwise when using a new version of the provider with a new major version of the Talos SDK, new machineconfig features will be enabled by default which could cause unexpected behavior.\n\n{{ if .HasExample -}}\n## Example Usage\n\n{{ tffile (printf .ExampleFile) }}\n{{- end }}\n{{ .SchemaMarkdown | trimspace }}\n"
  },
  {
    "path": "templates/guides/using_ephemeral_resources.md",
    "content": "---\npage_title: \"Using Ephemeral Resources - talos Provider\"\nsubcategory: \"\"\ndescription: |-\n  Learn how to use ephemeral resources in the Talos provider to prevent secrets from being stored in Terraform state\n---\n\n# Using Ephemeral Resources in the Talos Provider\n\nEphemeral resources are Terraform resources that are essentially temporary. They allow you to access and use data in your configurations without that data being stored in Terraform state. This is particularly important for sensitive data like machine secrets, certificates, and kubeconfig files.\n\nEphemeral resources are available in Terraform v1.10 and later. For more information, see the [official HashiCorp documentation for Ephemeral Resources](https://developer.hashicorp.com/terraform/language/resources/ephemeral).\n\n## Available Ephemeral Resources\n\nThe Talos provider includes five ephemeral resources:\n\n- [`talos_machine_secrets`](https://registry.terraform.io/providers/siderolabs/talos/latest/docs/ephemeral-resources/machine_secrets) - Generate machine secrets without storing them in state\n- [`talos_machine_configuration`](https://registry.terraform.io/providers/siderolabs/talos/latest/docs/ephemeral-resources/machine_configuration) - Generate machine configuration without storing secrets in state\n- [`talos_client_configuration`](https://registry.terraform.io/providers/siderolabs/talos/latest/docs/ephemeral-resources/client_configuration) - Generate client configuration (talosconfig) without storing credentials in state\n- [`talos_cluster_kubeconfig`](https://registry.terraform.io/providers/siderolabs/talos/latest/docs/ephemeral-resources/cluster_kubeconfig) - Retrieve kubeconfig without storing credentials in state\n- [`talos_cluster_health`](https://registry.terraform.io/providers/siderolabs/talos/latest/docs/ephemeral-resources/cluster_health) - Check cluster health without storing credentials in state\n\nThese complement the existing data sources and resources, allowing you to avoid storing credentials and secret values in your Terraform state.\n\n## Why Use Ephemeral Resources?\n\n**Security Benefits:**\n\n- Secrets never written to Terraform state files\n- Reduces risk of credential exposure through state files\n- Complies with security policies requiring secret-free state\n\n**When to Use:**\n\n- Generating Talos machine secrets\n- Creating machine configurations with sensitive data\n- Retrieving kubeconfig files\n- Any workflow where secrets shouldn't persist in state\n\n## Critical: Machine Secrets Persistence\n\n**IMPORTANT**: Do not use `ephemeral \"talos_machine_secrets\"` without also storing them in a secret manager. Generating ephemeral machine secrets without persistence would create **new secrets on every Terraform run**, causing:\n\n- Unpredictable changes to dependent resources\n- Need to reconfigure all cluster nodes\n- Loss of access to the cluster with previous credentials\n- Non-deterministic infrastructure state\n\n### Correct Pattern: Secret Manager Integration\n\nMachine secrets should be:\n\n1. Generated once and stored in a secret manager (Vault, AWS Secrets Manager, etc.)\n2. Retrieved ephemerally from the secret manager when needed\n3. Used to generate machine configurations deterministically\n\nThis ensures:\n\n- Secrets remain stable across Terraform runs\n- No secrets stored in Terraform state\n- Deterministic, reproducible infrastructure\n- Compliance with security policies\n\n## Using Ephemeral Resources with Write-Only Attributes\n\nEphemeral resources are a source of ephemeral data, and they can be referenced in your configuration just like the attributes of resources and data sources. However, a field that references an ephemeral resource must be capable of handling ephemeral data.\n\nThe Talos provider includes write-only attributes that accept ephemeral values:\n\n- `machine_configuration_input_wo` - Write-only alternative to `machine_configuration_input` on `talos_machine_configuration_apply` resource (requires Terraform 1.11+)\n\n## Example: Using Vault for Secret Persistence\n\nThis example demonstrates the correct pattern for managing Talos machine secrets with Vault. Both secret generation and retrieval can coexist in the same configuration:\n\n```terraform\nterraform {\n  required_version = \">= 1.11\"\n  required_providers {\n    talos = {\n      source  = \"siderolabs/talos\"\n      version = \"~> 0.11\"\n    }\n    vault = {\n      source  = \"hashicorp/vault\"\n      version = \"~> 5.0\"\n    }\n  }\n}\n\n# Step 1: Generate and store secrets in Vault\n# The ephemeral resource generates secrets only when needed (first run)\n# After initial creation, this won't be evaluated because data_json_wo_version is hardcoded\nephemeral \"talos_machine_secrets\" \"this\" {}\n\nresource \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = \"secret\"\n  name  = \"talos-cluster-${var.cluster_name}\"\n\n  # Write-only attributes prevent secrets from being stored in Terraform state\n  data_json_wo = jsonencode({\n    machine_secrets      = ephemeral.talos_machine_secrets.this.machine_secrets\n    client_configuration = ephemeral.talos_machine_secrets.this.client_configuration\n  })\n  # Hardcoded version prevents unnecessary refreshes after initial creation\n  data_json_wo_version = 1\n}\n\n# Step 2: Retrieve secrets ephemerally from Vault\n# This runs on every terraform operation but values are never stored in state\n# Referencing the resource attributes creates implicit dependency on the secret\nephemeral \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = vault_kv_secret_v2.talos_secrets.mount\n  name  = vault_kv_secret_v2.talos_secrets.name\n}\n\nlocals {\n  # Decode the secret data\n  talos_data = jsondecode(ephemeral.vault_kv_secret_v2.talos_secrets.data_json)\n}\n\n# Step 3: Generate machine configuration using retrieved secrets\nephemeral \"talos_machine_configuration\" \"controlplane\" {\n  cluster_name     = var.cluster_name\n  cluster_endpoint = var.cluster_endpoint\n  machine_type     = \"controlplane\"\n  machine_secrets  = local.talos_data.machine_secrets\n}\n\n# Step 4: Apply configuration using write-only input\nresource \"talos_machine_configuration_apply\" \"controlplane\" {\n  client_configuration_wo        = local.talos_data.client_configuration\n  machine_configuration_input_wo = ephemeral.talos_machine_configuration.controlplane.machine_configuration\n  node                           = var.controlplane_node\n\n  # Note: machine_configuration computed attribute will be null in state\n  # This is expected behavior for secret-free operation\n}\n```\n\n**Secret-Free Operation:**\n\nWhen using write-only attributes (`_wo` variants), the provider ensures zero secrets leak into state:\n\n- **Write-only inputs** (`client_configuration_wo`, `machine_configuration_input_wo`): Never stored in state\n- **Computed outputs** (`machine_configuration`): Automatically set to null in state when using write-only inputs\n\nThe provider computes the machine configuration internally during apply operations without persisting it. This provides complete secret-free operation while maintaining full functionality.\n\n**How This Works:**\n\n1. **First Run**:\n   - Secrets are generated ephemerally\n   - Stored in Vault with version 1\n   - Retrieved from Vault for immediate use\n   - All in a single `terraform apply` (Terraform handles the ordering automatically)\n\n2. **Subsequent Runs**:\n   - The `vault_kv_secret_v2` resource doesn't need updates (version is hardcoded)\n   - The `ephemeral \"talos_machine_secrets\"` isn't evaluated (no dependent resources need it)\n   - Secrets are retrieved ephemerally from Vault for use in configuration\n\n**Key Benefits:**\n\n- Works in a single run on first apply\n- Both blocks coexist permanently in your configuration\n- Terraform handles all dependencies automatically\n- No secrets stored in Terraform state\n\n### Alternative Pattern: External Secret Generation\n\nIf you prefer to manage secret generation outside Terraform:\n\n```bash\n# Generate secrets manually using talosctl\ntalosctl gen secrets -o secrets.yaml\n\n# Store in Vault using vault CLI\nvault kv put secret/talos-cluster-prod \\\n  machine_secrets=\"$(yq -o=json '.machine_secrets' secrets.yaml)\" \\\n  client_configuration=\"$(yq -o=json '.client_configuration' secrets.yaml)\"\n```\n\nThen your Terraform configuration only needs the retrieval part:\n\n```terraform\nephemeral \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = \"secret\"\n  name  = \"talos-cluster-prod\"\n}\n\nlocals {\n  talos_data = jsondecode(ephemeral.vault_kv_secret_v2.talos_secrets.data_json)\n}\n\nephemeral \"talos_machine_configuration\" \"controlplane\" {\n  cluster_name     = \"prod-cluster\"\n  cluster_endpoint = \"https://10.5.0.2:6443\"\n  machine_type     = \"controlplane\"\n  machine_secrets  = local.talos_data.machine_secrets\n}\n```\n\n## Example: Generating Kubeconfig Ephemerally from Machine Secrets\n\nThis example shows how to generate a kubeconfig ephemerally from machine secrets stored in Vault.\nThe kubeconfig is generated locally from the Kubernetes CA key — no live cluster required.\n\n### Simple usage (CA-pinned timestamps)\n\nWhen `not_before` is omitted, the admin certificate validity window is taken from the K8s CA's\nown timestamps (set once when the cluster was created). The output is byte-identical on every\nplan as long as `machine_secrets` does not change.\n\n```terraform\n# Retrieve stored secrets from Vault\nephemeral \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = \"secret\"\n  name  = \"talos-cluster-prod\"\n}\n\nlocals {\n  talos_data = jsondecode(ephemeral.vault_kv_secret_v2.talos_secrets.data_json)\n}\n\n# Generate kubeconfig without storing in state\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n  cluster_name    = \"prod-cluster\"\n  machine_secrets = local.talos_data.machine_secrets\n  endpoint        = \"https://10.5.0.2:6443\"\n}\n\n# Output the kubeconfig (marked as ephemeral)\noutput \"kubeconfig\" {\n  value     = ephemeral.talos_cluster_kubeconfig.this.kubeconfig_raw\n  sensitive = true\n  ephemeral = true\n}\n```\n\n### Recommended pattern for Vault-backed workflows (explicit `not_before`)\n\nWhen storing `kubeconfig_raw` in a Vault KV secret (or any resource that detects byte changes),\nuse a `terraform_data` resource to persist a stable `not_before` timestamp in Terraform state.\nThis pins the admin certificate validity window so `kubeconfig_raw` is byte-identical across\nall plan invocations — no `ignore_changes` or `data_json_wo_version` bumps required until you\nexplicitly rotate the certificate.\n\n```terraform\n# Persist the admin cert NotBefore timestamp in regular Terraform state.\n# Use ignore_changes so it is set once and never updated automatically.\n# To rotate the cert: taint this resource and re-apply.\nresource \"terraform_data\" \"kubeconfig_nbf\" {\n  input = plantimestamp()\n  lifecycle {\n    ignore_changes = [input]\n  }\n}\n\n# Generate kubeconfig with pinned timestamps\nephemeral \"talos_cluster_kubeconfig\" \"this\" {\n  cluster_name    = \"prod-cluster\"\n  machine_secrets = local.talos_data.machine_secrets\n  endpoint        = \"https://10.5.0.2:6443\"\n  not_before      = terraform_data.kubeconfig_nbf.output\n  crt_ttl         = \"87600h\"\n}\n\n# Store kubeconfig in Vault — kubeconfig_raw is stable so this resource\n# only updates when machine_secrets or not_before change.\nresource \"vault_kv_secret_v2\" \"kubeconfig\" {\n  mount = \"secret\"\n  name  = \"kubeconfig-prod-cluster\"\n\n  data_json_wo         = jsonencode({ kubeconfig = ephemeral.talos_cluster_kubeconfig.this.kubeconfig_raw })\n  data_json_wo_version = 1\n}\n```\n\n**Certificate rotation**: taint `terraform_data.kubeconfig_nbf` to force a new `not_before`,\nwhich produces a new cert and triggers a `data_json_wo_version` bump on the Vault secret.\n\n**Note**: The kubeconfig is generated locally from the machine secrets and does not require\na running cluster.\n\n## Alternative Secret Managers\n\nWhile the examples above use HashiCorp Vault, you can use any secret manager that supports:\n\n- Storing secrets via Terraform resources\n- Retrieving secrets via ephemeral resources\n\n### AWS Secrets Manager Example\n\n```terraform\n# Store secrets in AWS Secrets Manager\nresource \"aws_secretsmanager_secret\" \"talos_secrets\" {\n  name = \"talos-cluster-${var.cluster_name}\"\n}\n\nresource \"aws_secretsmanager_secret_version\" \"talos_secrets\" {\n  secret_id = aws_secretsmanager_secret.talos_secrets.id\n  secret_string = jsonencode({\n    machine_secrets      = talos_machine_secrets.this.machine_secrets\n    client_configuration = talos_machine_secrets.this.client_configuration\n  })\n}\n\n# Note: AWS provider doesn't yet have ephemeral resources for Secrets Manager\n# You would use a data source, which still stores in state\n# Watch for AWS provider updates adding ephemeral support\n```\n\n### Azure Key Vault Example\n\n```terraform\n# Store secrets in Azure Key Vault\nresource \"azurerm_key_vault_secret\" \"talos_secrets\" {\n  name         = \"talos-cluster-${var.cluster_name}\"\n  value        = jsonencode({\n    machine_secrets      = talos_machine_secrets.this.machine_secrets\n    client_configuration = talos_machine_secrets.this.client_configuration\n  })\n  key_vault_id = azurerm_key_vault.main.id\n}\n\n# Note: Azure provider doesn't yet have ephemeral resources for Key Vault\n# You would use a data source for now\n```\n\n## Important Considerations\n\n### Terraform Version Requirements\n\n- **Terraform 1.10+**: Supports ephemeral resources only (no write-only attributes)\n- **Terraform 1.11+**: Supports both ephemeral resources and write-only attributes\n- **OpenTofu 1.11+**: Supports both ephemeral resources and write-only attributes\n  - Note: OpenTofu 1.10 does NOT support ephemeral resources (they were introduced in 1.11)\n\n**For the examples in this guide**: Terraform 1.11+ or OpenTofu 1.11+ required (uses write-only attributes)\n\n### Compatibility with Existing Resources\n\nEphemeral resources complement existing data sources and resources:\n\n- **Data sources** (e.g., `data.talos_machine_configuration`) - Still work, but store output in state\n- **Ephemeral resources** (e.g., `ephemeral.talos_machine_configuration`) - Same functionality, no state storage\n\nYou can migrate existing configurations to ephemeral resources by:\n\n1. Changing `data \"talos_machine_configuration\"` to `ephemeral \"talos_machine_configuration\"`\n2. Updating references from `data.talos_machine_configuration.this` to `ephemeral.talos_machine_configuration.this`\n3. Using write-only attributes (e.g., `machine_configuration_input_wo`) where applicable\n\n## Migration Guide\n\n### From Data Source to Ephemeral Resource with Vault\n\n**Before (using data source):**\n\n```terraform\nresource \"talos_machine_secrets\" \"this\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"my-cluster\"\n  cluster_endpoint = \"https://10.5.0.2:6443\"\n  machine_type     = \"controlplane\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.2\"\n}\n```\n\n**After (using ephemeral resources with Vault):**\n\nStep 1 - Store existing secrets in Vault (one-time migration):\n\n```terraform\n# Assuming you have existing talos_machine_secrets resource\nresource \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = \"secret\"\n  name  = \"talos-cluster-my-cluster\"\n\n  data_json_wo = jsonencode({\n    machine_secrets      = talos_machine_secrets.this.machine_secrets\n    client_configuration = talos_machine_secrets.this.client_configuration\n  })\n}\n```\n\nStep 2 - Use ephemeral resources to retrieve from Vault:\n\n```terraform\n# Retrieve secrets from Vault ephemerally\n# Reference the resource to create implicit dependency\nephemeral \"vault_kv_secret_v2\" \"talos_secrets\" {\n  mount = vault_kv_secret_v2.talos_secrets.mount\n  name  = vault_kv_secret_v2.talos_secrets.name\n}\n\nlocals {\n  talos_data = jsondecode(ephemeral.vault_kv_secret_v2.talos_secrets.data_json)\n}\n\n# Generate configuration ephemerally\nephemeral \"talos_machine_configuration\" \"this\" {\n  cluster_name     = \"my-cluster\"\n  cluster_endpoint = \"https://10.5.0.2:6443\"\n  machine_type     = \"controlplane\"\n  machine_secrets  = local.talos_data.machine_secrets\n}\n\n# Apply configuration using write-only attribute\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration_wo        = local.talos_data.client_configuration\n  machine_configuration_input_wo = ephemeral.talos_machine_configuration.this.machine_configuration\n  node                           = \"10.5.0.2\"\n}\n```\n\nStep 3 - After verifying the migration works, remove the `talos_machine_secrets` resource from your state:\n\n```bash\nterraform state rm talos_machine_secrets.this\n```\n\n**Benefits:**\n\n- Machine secrets stored securely in Vault, not in Terraform state\n- Secrets remain stable across Terraform runs\n- Machine configuration never stored in state\n- Deterministic infrastructure state\n- Improved security and compliance\n"
  },
  {
    "path": "templates/guides/version-0.2-upgrade.html.md",
    "content": "---\npage_title: \"Terraform Talos Provider Version 0.2 Upgrade Guide\"\ndescription: |-\n  Terraform Talos Provider Version 0.2 Upgrade Guide\n---\n\n# Terraform Talos Provider Version 0.2 Upgrade Guide <!-- omit in toc -->\n\nVersion 0.2 of the Talos Terraform provider is a major release and include some breaking chages. This guide will walk you through the changes and how to upgrade your Terraform configuration.\n\n~> **NOTE:** Version 0.2 of the Talos Terraform provider drops support for the following resources:\n\n> * `talos_client_configuration`\n> * `talos_cluster_kubeconfig`\n> * `talos_machine_configuration_controlplane`\n> * `talos_machine_configuration_worker`\n\nThe following table lists the resources that have been removed and the new resources that replace them.\n\n| Removed Resource                           | Type     | New Resource                  | Type          |\n| ------------------------------------------ | -------- | ----------------------------- | ------------- |\n| `talos_client_configuration`               | Resource | `talos_client_configuration`  | Data Source   |\n| `talos_cluster_kubeconfig`                 | Resource | `talos_cluster_kubeconfig`    | Data Source   |\n| `talos_machine_configuration_controlplane` | Resource | `talos_machine_configuration` | Data Resource |\n| `talos_machine_configuration_worker`       | Resource | `talos_machine_configuration` | Data Resource |\n\n## Upgrade topics: <!-- omit in toc -->\n\n- [Upgrading `talos_client_configuration` resource](#upgrading-talos_client_configuration-resource)\n- [Upgrading `talos_cluster_kubeconfig` resource](#upgrading-talos_cluster_kubeconfig-resource)\n- [Upgrading `talos_machine_configuration_controlplane` resource](#upgrading-talos_machine_configuration_controlplane-resource)\n- [Upgrading `talos_machine_configuration_worker` resource](#upgrading-talos_machine_configuration_worker-resource)\n\n### Upgrading `talos_client_configuration` resource\n\nThe `talos_client_configuration` resource has been removed. The `talos_client_configuration` data source should be used instead.\n\nFor example if the following resource was used:\n\n```hcl\nresource \"talos_machine_secrets\" \"this\" {}\n\nresource \"talos_client_configuration\" \"talosconfig\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = talos_machine_secrets.this.machine_secrets\n}\n```\n\n`talos_client_configuration` resource should be first removed from the state:\n\n```bash\nterraform state rm talos_client_configuration.talosconfig\n```\n\nand the code should be updated to:\n\n```hcl\nresource \"talos_machine_secrets\" \"machine_secrets\" {}\n\ndata \"talos_client_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  client_configuration = talos_machine_secrets.this.client_configuration\n}\n```\n\n### Upgrading `talos_cluster_kubeconfig` resource\n\nThe `talos_cluster_kubeconfig` resource has been removed. The `talos_cluster_kubeconfig` data source should be used instead.\n\nFor example if the following resource was used:\n\n```hcl\nresource \"talos_machine_secrets\" \"this\" {}\n\nresource \"talos_client_configuration\" \"this\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_cluster_kubeconfig\" \"kubeconfig\" {\n  talos_config = talos_client_configuration.this.talos_config\n  endpoint     = \"10.5.0.2\"\n  node         = \"10.5.0.2\"\n}\n```\n\n`talos_cluster_kubeconfig` resource should be first removed from the state:\n\n```bash\nterraform state rm talos_cluster_kubeconfig.kubeconfig\n```\n\nand the code should be updated to:\n\n```hcl\nresource \"talos_machine_secrets\" \"machine_secrets\" {}\n\ndata \"talos_cluster_kubeconfig\" \"this\" {\n  client_configuration = talos_machine_secrets.this.client_configuration\n  node                 = \"10.5.0.2\"\n}\n```\n\n### Upgrading `talos_machine_configuration_controlplane` resource\n\nThe `talos_machine_configuration_controlplane` resource has been removed. The `talos_machine_configuration` data source should be used instead.\n\nFor example if the following resource was used:\n\n```hcl\nresource \"talos_machine_secrets\" \"this\" {}\n\nresource \"talos_client_configuration\" \"this\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_controlplane\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  cluster_endpoint = \"https://10.5.0.2:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  talos_config          = talos_client_configuration.this.talos_config\n  machine_configuration = talos_machine_configuration_controlplane.this.machine_config\n  node                  = \"10.5.0.2\"\n  endpoint              = \"10.5.0.2\"\n}\n```\n\n`talos_machine_configuration_controlplane` resource should be first removed from the state:\n\n```bash\nterraform state rm talos_machine_configuration_controlplane.cp\n```\n\nand the code should be updated to:\n\n```hcl\nresource \"talos_machine_secrets\" \"machine_secrets\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  cluster_endpoint     = \"https://10.5.0.2:6443\"\n  machine_type         = \"controlplane\"\n  talos_version        = talos_machine_secrets.this.talos_version\n  machine_secrets      = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.2\"\n}\n```\n\n### Upgrading `talos_machine_configuration_worker` resource\n\nThe `talos_machine_configuration_worker` resource has been removed. The `talos_machine_configuration` data source should be used instead.\n\nFor example if the following resource was used:\n\n```hcl\nresource \"talos_machine_secrets\" \"this\" {}\n\nresource \"talos_client_configuration\" \"this\" {\n  cluster_name    = \"example-cluster\"\n  machine_secrets = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_worker\" \"this\" {\n  cluster_name     = \"example-cluster\"\n  cluster_endpoint = \"https://10.5.0.2:6443\"\n  machine_secrets  = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  talos_config          = talos_client_configuration.this.talos_config\n  machine_configuration = talos_machine_configuration_worker.this.machine_config\n  node                  = \"10.5.0.3\"\n  endpoint              = \"10.5.0.3\"\n}\n```\n\n`talos_machine_configuration_worker` resource should be first removed from the state:\n\n```bash\nterraform state rm talos_machine_configuration_worker.worker\n```\n\nand the code should be updated to:\n\n```hcl\nresource \"talos_machine_secrets\" \"machine_secrets\" {}\n\ndata \"talos_machine_configuration\" \"this\" {\n  cluster_name         = \"example-cluster\"\n  cluster_endpoint     = \"https://10.5.0.2:6443\"\n  machine_type         = \"worker\"\n  talos_version        = talos_machine_secrets.this.talos_version\n  machine_secrets      = talos_machine_secrets.this.machine_secrets\n}\n\nresource \"talos_machine_configuration_apply\" \"this\" {\n  client_configuration        = talos_machine_secrets.this.client_configuration\n  machine_configuration_input = data.talos_machine_configuration.this.machine_configuration\n  node                        = \"10.5.0.3\"\n}\n```\n"
  },
  {
    "path": "templates/index.md.tmpl",
    "content": "---\npage_title: \"Provider: Talos\"\ndescription: |-\n  The Talos provider is used to manage a Talos cluster config generation and initial setup.\n---\n\n# Talos Provider\n\nTalos provider allows to generate configs for a Talos cluster and apply them to the nodes, bootstrap nodes, check cluster health, and retrieve `kubeconfig` and `talosconfig`.\n\nComplete usages for this provider across a variety of environments can be found [here](https://github.com/siderolabs/contrib/tree/main/examples/terraform).\n"
  },
  {
    "path": "templates/resources.md.tmpl",
    "content": "---\npage_title: \"{{.Name}} {{.Type}} - {{.RenderedProviderName}}\"\nsubcategory: \"\"\ndescription: |-\n{{ .Description | plainmarkdown | trimspace | prefixlines \"  \" }}\n---\n\n# {{.Name}} ({{.Type}})\n\n{{ .Description | trimspace }}\n\n{{ if .HasExample -}}\n## Example Usage\n\n{{ tffile (printf .ExampleFile) }}\n{{- end }}\n{{ .SchemaMarkdown | trimspace }}\n{{ if .HasImport -}}\n## Import\n\nImport is supported using the following syntax:\n\n{{ tffile (printf .ImportFile) }}\n{{- end }}\n"
  },
  {
    "path": "terraform-registry-manifest.json",
    "content": "{\n    \"version\": 1,\n    \"metadata\": {\n        \"protocol_versions\": [\n            \"5.0\"\n        ]\n    }\n}"
  },
  {
    "path": "tools/go.mod",
    "content": "module github.com/siderolabs/terraform-provider-talos/tools\n\ngo 1.26.1\n\ntool (\n\tgithub.com/anchore/syft/cmd/syft\n\tgolang.org/x/vuln/cmd/govulncheck\n)\n\nrequire github.com/hashicorp/terraform-plugin-docs v0.24.0\n\nrequire (\n\tcel.dev/expr v0.25.1 // indirect\n\tcloud.google.com/go v0.123.0 // indirect\n\tcloud.google.com/go/auth v0.18.1 // indirect\n\tcloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect\n\tcloud.google.com/go/compute/metadata v0.9.0 // indirect\n\tcloud.google.com/go/iam v1.5.3 // indirect\n\tcloud.google.com/go/monitoring v1.24.3 // indirect\n\tcloud.google.com/go/storage v1.60.0 // indirect\n\tcyphar.com/go-pathrs v0.2.1 // indirect\n\tdario.cat/mergo v1.0.2 // indirect\n\tgithub.com/BurntSushi/toml v1.6.0 // indirect\n\tgithub.com/CycloneDX/cyclonedx-go v0.10.0 // indirect\n\tgithub.com/DataDog/zstd v1.5.7 // indirect\n\tgithub.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect\n\tgithub.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect\n\tgithub.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect\n\tgithub.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect\n\tgithub.com/Masterminds/goutils v1.1.1 // indirect\n\tgithub.com/Masterminds/semver/v3 v3.4.0 // indirect\n\tgithub.com/Masterminds/sprig/v3 v3.3.0 // indirect\n\tgithub.com/Microsoft/go-winio v0.6.2 // indirect\n\tgithub.com/Microsoft/hcsshim v0.14.0-rc.1 // indirect\n\tgithub.com/OneOfOne/xxhash v1.2.8 // indirect\n\tgithub.com/ProtonMail/go-crypto v1.4.0 // indirect\n\tgithub.com/STARRY-S/zip v0.2.3 // indirect\n\tgithub.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect\n\tgithub.com/acobaugh/osrelease v0.1.0 // indirect\n\tgithub.com/adrg/xdg v0.5.3 // indirect\n\tgithub.com/agext/levenshtein v1.2.3 // indirect\n\tgithub.com/anchore/bubbly v0.0.0-20250717181826-8a411f9d8cbf // indirect\n\tgithub.com/anchore/clio v0.0.0-20250715152405-a0fa658e5084 // indirect\n\tgithub.com/anchore/fangs v0.0.0-20250716230140-94c22408c232 // indirect\n\tgithub.com/anchore/go-collections v0.0.0-20251016125210-a3c352120e8c // indirect\n\tgithub.com/anchore/go-homedir v0.0.0-20250319154043-c29668562e4d // indirect\n\tgithub.com/anchore/go-logger v0.0.0-20250318195838-07ae343dd722 // indirect\n\tgithub.com/anchore/go-lzo v0.1.0 // indirect\n\tgithub.com/anchore/go-macholibre v0.0.0-20250320151634-807da7ad2331 // indirect\n\tgithub.com/anchore/go-rpmdb v0.0.0-20250516171929-f77691e1faec // indirect\n\tgithub.com/anchore/go-struct-converter v0.1.0 // indirect\n\tgithub.com/anchore/go-sync v0.0.0-20250714163430-add63db73ad1 // indirect\n\tgithub.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 // indirect\n\tgithub.com/anchore/packageurl-go v0.1.1-0.20250220190351-d62adb6e1115 // indirect\n\tgithub.com/anchore/stereoscope v0.1.22 // indirect\n\tgithub.com/anchore/syft v1.42.3 // indirect\n\tgithub.com/andybalholm/brotli v1.2.0 // indirect\n\tgithub.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect\n\tgithub.com/aquasecurity/go-pep440-version v0.0.1 // indirect\n\tgithub.com/aquasecurity/go-version v0.0.1 // indirect\n\tgithub.com/armon/go-radix v1.0.0 // indirect\n\tgithub.com/aws/aws-sdk-go-v2 v1.41.2 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/config v1.32.10 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/credentials v1.19.10 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/s3 v1.96.0 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/signin v1.0.6 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/sso v1.30.11 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15 // indirect\n\tgithub.com/aws/aws-sdk-go-v2/service/sts v1.41.7 // indirect\n\tgithub.com/aws/smithy-go v1.24.1 // indirect\n\tgithub.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect\n\tgithub.com/becheran/wildmatch-go v1.0.0 // indirect\n\tgithub.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect\n\tgithub.com/bgentry/speakeasy v0.1.0 // indirect\n\tgithub.com/bitnami/go-version v0.0.0-20250505154626-452e8c5ee607 // indirect\n\tgithub.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect\n\tgithub.com/bmatcuk/doublestar/v4 v4.10.0 // indirect\n\tgithub.com/bodgit/plumbing v1.3.0 // indirect\n\tgithub.com/bodgit/sevenzip v1.6.1 // indirect\n\tgithub.com/bodgit/windows v1.0.1 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/charmbracelet/bubbles v1.0.0 // indirect\n\tgithub.com/charmbracelet/bubbletea v1.3.10 // indirect\n\tgithub.com/charmbracelet/colorprofile v0.4.1 // indirect\n\tgithub.com/charmbracelet/harmonica v0.2.0 // indirect\n\tgithub.com/charmbracelet/lipgloss v1.1.0 // indirect\n\tgithub.com/charmbracelet/x/ansi v0.11.6 // indirect\n\tgithub.com/charmbracelet/x/cellbuf v0.0.15 // indirect\n\tgithub.com/charmbracelet/x/term v0.2.2 // indirect\n\tgithub.com/clipperhouse/displaywidth v0.10.0 // indirect\n\tgithub.com/clipperhouse/uax29/v2 v2.6.0 // indirect\n\tgithub.com/cloudflare/circl v1.6.3 // indirect\n\tgithub.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect\n\tgithub.com/containerd/cgroups/v3 v3.1.2 // indirect\n\tgithub.com/containerd/containerd/api v1.10.0 // indirect\n\tgithub.com/containerd/containerd/v2 v2.2.1 // indirect\n\tgithub.com/containerd/continuity v0.4.5 // indirect\n\tgithub.com/containerd/errdefs v1.0.0 // indirect\n\tgithub.com/containerd/errdefs/pkg v0.3.0 // indirect\n\tgithub.com/containerd/fifo v1.1.0 // indirect\n\tgithub.com/containerd/log v0.1.0 // indirect\n\tgithub.com/containerd/platforms v1.0.0-rc.2 // indirect\n\tgithub.com/containerd/plugin v1.0.0 // indirect\n\tgithub.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect\n\tgithub.com/containerd/ttrpc v1.2.7 // indirect\n\tgithub.com/containerd/typeurl/v2 v2.2.3 // indirect\n\tgithub.com/cyphar/filepath-securejoin v0.6.0 // indirect\n\tgithub.com/deitch/magic v0.0.0-20240306090643-c67ab88f10cb // indirect\n\tgithub.com/diskfs/go-diskfs v1.7.0 // indirect\n\tgithub.com/distribution/reference v0.6.0 // indirect\n\tgithub.com/docker/cli v29.3.0+incompatible // indirect\n\tgithub.com/docker/distribution v2.8.3+incompatible // indirect\n\tgithub.com/docker/docker-credential-helpers v0.9.5 // indirect\n\tgithub.com/docker/go-connections v0.6.0 // indirect\n\tgithub.com/docker/go-units v0.5.0 // indirect\n\tgithub.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect\n\tgithub.com/dustin/go-humanize v1.0.1 // indirect\n\tgithub.com/elliotchance/phpserialize v1.4.0 // indirect\n\tgithub.com/emirpasic/gods v1.18.1 // indirect\n\tgithub.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect\n\tgithub.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect\n\tgithub.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect\n\tgithub.com/facebookincubator/nvdtools v0.1.5 // indirect\n\tgithub.com/fatih/color v1.18.0 // indirect\n\tgithub.com/felixge/fgprof v0.9.5 // indirect\n\tgithub.com/felixge/httpsnoop v1.0.4 // indirect\n\tgithub.com/fsnotify/fsnotify v1.9.0 // indirect\n\tgithub.com/gabriel-vasile/mimetype v1.4.13 // indirect\n\tgithub.com/github/go-spdx/v2 v2.4.0 // indirect\n\tgithub.com/glebarez/go-sqlite v1.22.0 // indirect\n\tgithub.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect\n\tgithub.com/go-git/go-billy/v5 v5.8.0 // indirect\n\tgithub.com/go-git/go-git/v5 v5.17.0 // indirect\n\tgithub.com/go-jose/go-jose/v4 v4.1.3 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/go-restruct/restruct v1.2.0-alpha // indirect\n\tgithub.com/go-viper/mapstructure/v2 v2.5.0 // indirect\n\tgithub.com/goccy/go-yaml v1.19.2 // indirect\n\tgithub.com/gogo/protobuf v1.3.2 // indirect\n\tgithub.com/gohugoio/hashstructure v0.6.0 // indirect\n\tgithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect\n\tgithub.com/google/go-cmp v0.7.0 // indirect\n\tgithub.com/google/go-containerregistry v0.21.2 // indirect\n\tgithub.com/google/licensecheck v0.3.1 // indirect\n\tgithub.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5 // indirect\n\tgithub.com/google/s2a-go v0.1.9 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect\n\tgithub.com/googleapis/gax-go/v2 v2.17.0 // indirect\n\tgithub.com/gookit/color v1.6.0 // indirect\n\tgithub.com/gpustack/gguf-parser-go v0.24.0 // indirect\n\tgithub.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.70 // indirect\n\tgithub.com/hashicorp/cli v1.1.7 // indirect\n\tgithub.com/hashicorp/errwrap v1.1.0 // indirect\n\tgithub.com/hashicorp/go-checkpoint v0.5.0 // indirect\n\tgithub.com/hashicorp/go-cleanhttp v0.5.2 // indirect\n\tgithub.com/hashicorp/go-getter v1.8.5 // indirect\n\tgithub.com/hashicorp/go-multierror v1.1.1 // indirect\n\tgithub.com/hashicorp/go-retryablehttp v0.7.7 // indirect\n\tgithub.com/hashicorp/go-uuid v1.0.3 // indirect\n\tgithub.com/hashicorp/go-version v1.8.0 // indirect\n\tgithub.com/hashicorp/golang-lru/v2 v2.0.7 // indirect\n\tgithub.com/hashicorp/hc-install v0.9.2 // indirect\n\tgithub.com/hashicorp/hcl/v2 v2.24.0 // indirect\n\tgithub.com/hashicorp/terraform-exec v0.24.0 // indirect\n\tgithub.com/hashicorp/terraform-json v0.27.2 // indirect\n\tgithub.com/henvic/httpretty v0.1.4 // indirect\n\tgithub.com/huandu/xstrings v1.5.0 // indirect\n\tgithub.com/iancoleman/strcase v0.3.0 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect\n\tgithub.com/jedib0t/go-pretty/v6 v6.7.8 // indirect\n\tgithub.com/jinzhu/copier v0.4.0 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953 // indirect\n\tgithub.com/kevinburke/ssh_config v1.2.0 // indirect\n\tgithub.com/klauspost/compress v1.18.4 // indirect\n\tgithub.com/klauspost/pgzip v1.2.6 // indirect\n\tgithub.com/lucasb-eyer/go-colorful v1.3.0 // indirect\n\tgithub.com/mattn/go-colorable v0.1.14 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75 // indirect\n\tgithub.com/mattn/go-runewidth v0.0.19 // indirect\n\tgithub.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect\n\tgithub.com/mholt/archives v0.1.5 // indirect\n\tgithub.com/mikelolasagasti/xz v1.0.1 // indirect\n\tgithub.com/minio/minlz v1.0.1 // indirect\n\tgithub.com/mitchellh/copystructure v1.2.0 // indirect\n\tgithub.com/mitchellh/go-homedir v1.1.0 // indirect\n\tgithub.com/mitchellh/go-wordwrap v1.0.1 // indirect\n\tgithub.com/mitchellh/reflectwalk v1.0.2 // indirect\n\tgithub.com/moby/docker-image-spec v1.3.1 // indirect\n\tgithub.com/moby/locker v1.0.1 // indirect\n\tgithub.com/moby/moby/api v1.54.0 // indirect\n\tgithub.com/moby/moby/client v0.3.0 // indirect\n\tgithub.com/moby/sys/mountinfo v0.7.2 // indirect\n\tgithub.com/moby/sys/sequential v0.6.0 // indirect\n\tgithub.com/moby/sys/signal v0.7.1 // indirect\n\tgithub.com/moby/sys/user v0.4.0 // indirect\n\tgithub.com/moby/sys/userns v0.1.0 // 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/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect\n\tgithub.com/muesli/cancelreader v0.2.2 // indirect\n\tgithub.com/muesli/termenv v0.16.0 // indirect\n\tgithub.com/ncruces/go-strftime v1.0.0 // indirect\n\tgithub.com/nix-community/go-nix v0.0.0-20250101154619-4bdde671e0a1 // indirect\n\tgithub.com/nwaples/rardecode/v2 v2.2.0 // indirect\n\tgithub.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect\n\tgithub.com/olekukonko/errors v1.2.0 // indirect\n\tgithub.com/olekukonko/ll v0.1.6 // indirect\n\tgithub.com/olekukonko/tablewriter v1.1.4 // indirect\n\tgithub.com/opencontainers/go-digest v1.0.0 // indirect\n\tgithub.com/opencontainers/image-spec v1.1.1 // indirect\n\tgithub.com/opencontainers/runtime-spec v1.3.0 // indirect\n\tgithub.com/opencontainers/selinux v1.13.1 // indirect\n\tgithub.com/pborman/indent v1.2.1 // indirect\n\tgithub.com/pelletier/go-toml v1.9.5 // indirect\n\tgithub.com/pelletier/go-toml/v2 v2.2.4 // indirect\n\tgithub.com/pierrec/lz4/v4 v4.1.22 // indirect\n\tgithub.com/pjbgf/sha1cd v0.4.0 // indirect\n\tgithub.com/pkg/errors v0.9.1 // indirect\n\tgithub.com/pkg/profile v1.7.0 // indirect\n\tgithub.com/pkg/xattr v0.4.12 // indirect\n\tgithub.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect\n\tgithub.com/posener/complete v1.2.3 // indirect\n\tgithub.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect\n\tgithub.com/rivo/uniseg v0.4.7 // indirect\n\tgithub.com/rust-secure-code/go-rustaudit v0.0.0-20250226111315-e20ec32e963c // indirect\n\tgithub.com/sagikazarmark/locafero v0.11.0 // indirect\n\tgithub.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect\n\tgithub.com/sassoftware/go-rpmutils v0.4.0 // indirect\n\tgithub.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e // indirect\n\tgithub.com/sergi/go-diff v1.4.0 // indirect\n\tgithub.com/shopspring/decimal v1.4.0 // indirect\n\tgithub.com/sirupsen/logrus v1.9.4 // indirect\n\tgithub.com/skeema/knownhosts v1.3.1 // indirect\n\tgithub.com/smallnest/ringbuffer v0.0.0-20241116012123-461381446e3d // indirect\n\tgithub.com/sorairolake/lzip-go v0.3.8 // indirect\n\tgithub.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect\n\tgithub.com/spdx/gordf v0.0.0-20250128162952-000978ccd6fb // indirect\n\tgithub.com/spdx/tools-golang v0.5.7 // indirect\n\tgithub.com/spf13/afero v1.15.0 // indirect\n\tgithub.com/spf13/cast v1.10.0 // indirect\n\tgithub.com/spf13/cobra v1.10.2 // indirect\n\tgithub.com/spf13/pflag v1.0.10 // indirect\n\tgithub.com/spf13/viper v1.21.0 // indirect\n\tgithub.com/spiffe/go-spiffe/v2 v2.6.0 // indirect\n\tgithub.com/subosito/gotenv v1.6.0 // indirect\n\tgithub.com/sylabs/sif/v2 v2.24.0 // indirect\n\tgithub.com/sylabs/squashfs v1.0.6 // indirect\n\tgithub.com/therootcompany/xz v1.0.1 // indirect\n\tgithub.com/ulikunitz/xz v0.5.15 // indirect\n\tgithub.com/vbatts/go-mtree v0.7.0 // indirect\n\tgithub.com/vbatts/tar-split v0.12.2 // indirect\n\tgithub.com/vifraa/gopom v1.0.0 // indirect\n\tgithub.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 // indirect\n\tgithub.com/wagoodman/go-progress v0.0.0-20260303201901-10176f79b2c0 // indirect\n\tgithub.com/xanzy/ssh-agent v0.3.3 // indirect\n\tgithub.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect\n\tgithub.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect\n\tgithub.com/yuin/goldmark v1.7.7 // indirect\n\tgithub.com/yuin/goldmark-meta v1.1.0 // indirect\n\tgithub.com/zclconf/go-cty v1.17.0 // indirect\n\tgithub.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1 // indirect\n\tgo.abhg.dev/goldmark/frontmatter v0.2.0 // indirect\n\tgo.opencensus.io v0.24.0 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.2.1 // indirect\n\tgo.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect\n\tgo.opentelemetry.io/otel v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/sdk v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.40.0 // indirect\n\tgo.yaml.in/yaml/v3 v3.0.4 // indirect\n\tgo4.org v0.0.0-20230225012048-214862532bf5 // indirect\n\tgolang.org/x/crypto v0.49.0 // indirect\n\tgolang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect\n\tgolang.org/x/mod v0.34.0 // indirect\n\tgolang.org/x/net v0.52.0 // indirect\n\tgolang.org/x/oauth2 v0.36.0 // indirect\n\tgolang.org/x/sync v0.20.0 // indirect\n\tgolang.org/x/sys v0.42.0 // indirect\n\tgolang.org/x/telemetry v0.0.0-20260311193753-579e4da9a98c // indirect\n\tgolang.org/x/term v0.41.0 // indirect\n\tgolang.org/x/text v0.35.0 // indirect\n\tgolang.org/x/time v0.15.0 // indirect\n\tgolang.org/x/tools v0.43.0 // indirect\n\tgolang.org/x/vuln v1.1.4 // indirect\n\tgolang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect\n\tgonum.org/v1/gonum v0.16.0 // indirect\n\tgoogle.golang.org/api v0.267.0 // indirect\n\tgoogle.golang.org/genproto v0.0.0-20260128011058-8636f8732409 // indirect\n\tgoogle.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20 // indirect\n\tgoogle.golang.org/grpc v1.79.3 // indirect\n\tgoogle.golang.org/protobuf v1.36.11 // indirect\n\tgopkg.in/warnings.v0 v0.1.2 // indirect\n\tgopkg.in/yaml.v2 v2.4.0 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n\tmodernc.org/libc v1.67.6 // indirect\n\tmodernc.org/mathutil v1.7.1 // indirect\n\tmodernc.org/memory v1.11.0 // indirect\n\tmodernc.org/sqlite v1.46.1 // indirect\n)\n"
  },
  {
    "path": "tools/go.sum",
    "content": "cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=\ncel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=\ncloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=\ncloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=\ncloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=\ncloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=\ncloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=\ncloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=\ncloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=\ncloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=\ncloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=\ncloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=\ncloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=\ncloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=\ncloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM=\ncloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=\ncloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=\ncloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=\ncloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs=\ncloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA=\ncloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=\ncloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=\ncloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=\ncloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc=\ncloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU=\ncloud.google.com/go/logging v1.13.1 h1:O7LvmO0kGLaHY/gq8cV7T0dyp6zJhYAOtZPX4TF3QtY=\ncloud.google.com/go/logging v1.13.1/go.mod h1:XAQkfkMBxQRjQek96WLPNze7vsOmay9H5PqfsNYDqvw=\ncloud.google.com/go/longrunning v0.8.0 h1:LiKK77J3bx5gDLi4SMViHixjD2ohlkwBi+mKA7EhfW8=\ncloud.google.com/go/longrunning v0.8.0/go.mod h1:UmErU2Onzi+fKDg2gR7dusz11Pe26aknR4kHmJJqIfk=\ncloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhOdsgaE=\ncloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ncloud.google.com/go/storage v1.60.0 h1:oBfZrSOCimggVNz9Y/bXY35uUcts7OViubeddTTVzQ8=\ncloud.google.com/go/storage v1.60.0/go.mod h1:q+5196hXfejkctrnx+VYU8RKQr/L3c0cBIlrjmiAKE0=\ncloud.google.com/go/trace v1.11.7 h1:kDNDX8JkaAG3R2nq1lIdkb7FCSi1rCmsEtKVsty7p+U=\ncloud.google.com/go/trace v1.11.7/go.mod h1:TNn9d5V3fQVf6s4SCveVMIBS2LJUqo73GACmq/Tky0s=\ncyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8=\ncyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc=\ndario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=\ndario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngithub.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=\ngithub.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=\ngithub.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=\ngithub.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/CycloneDX/cyclonedx-go v0.10.0 h1:7xyklU7YD+CUyGzSFIARG18NYLsKVn4QFg04qSsu+7Y=\ngithub.com/CycloneDX/cyclonedx-go v0.10.0/go.mod h1:vUvbCXQsEm48OI6oOlanxstwNByXjCZ2wuleUlwGEO8=\ngithub.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=\ngithub.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE=\ngithub.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=\ngithub.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=\ngithub.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=\ngithub.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 h1:UnDZ/zFfG1JhH/DqxIZYU/1CUAlTUScoXD/LcM2Ykk8=\ngithub.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0/go.mod h1:IA1C1U7jO/ENqm/vhi7V9YYpBsp+IMyqNrEN94N7tVc=\ngithub.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0 h1:7t/qx5Ost0s0wbA/VDrByOooURhp+ikYwv20i9Y07TQ=\ngithub.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0/go.mod h1:vB2GH9GAYYJTO3mEn8oYwzEdhlayZIdQz6zdzgUIRvA=\ngithub.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 h1:0s6TxfCu2KHkkZPnBfsQ2y5qia0jl3MMrmBhu3nCOYk=\ngithub.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc=\ngithub.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0=\ngithub.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc=\ngithub.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=\ngithub.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=\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/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=\ngithub.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=\ngithub.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=\ngithub.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=\ngithub.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=\ngithub.com/Microsoft/hcsshim v0.14.0-rc.1 h1:qAPXKwGOkVn8LlqgBN8GS0bxZ83hOJpcjxzmlQKxKsQ=\ngithub.com/Microsoft/hcsshim v0.14.0-rc.1/go.mod h1:hTKFGbnDtQb1wHiOWv4v0eN+7boSWAHyK/tNAaYZL0c=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=\ngithub.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=\ngithub.com/ProtonMail/go-crypto v1.4.0 h1:Zq/pbM3F5DFgJiMouxEdSVY44MVoQNEKp5d5QxIQceQ=\ngithub.com/ProtonMail/go-crypto v1.4.0/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo=\ngithub.com/STARRY-S/zip v0.2.3 h1:luE4dMvRPDOWQdeDdUxUoZkzUIpTccdKdhHHsQJ1fm4=\ngithub.com/STARRY-S/zip v0.2.3/go.mod h1:lqJ9JdeRipyOQJrYSOtpNAiaesFO6zVDsE8GIGFaoSk=\ngithub.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=\ngithub.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=\ngithub.com/acobaugh/osrelease v0.1.0 h1:Yb59HQDGGNhCj4suHaFQQfBps5wyoKLSSX/J/+UifRE=\ngithub.com/acobaugh/osrelease v0.1.0/go.mod h1:4bFEs0MtgHNHBrmHCt67gNisnabCRAlzdVasCEGHTWY=\ngithub.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=\ngithub.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=\ngithub.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=\ngithub.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/anchore/bubbly v0.0.0-20250717181826-8a411f9d8cbf h1:UY7SQkfVVaeGUpPZrJxqmTc8M0ZSWc5ChiKF6I6aL3I=\ngithub.com/anchore/bubbly v0.0.0-20250717181826-8a411f9d8cbf/go.mod h1:w8Br1ZKk1Nk82YRSh10pcD7LO7avPyFmNnaY1TRPgs0=\ngithub.com/anchore/clio v0.0.0-20250715152405-a0fa658e5084 h1:7DUAXEdAxoANPlDgxYiaSRKnWnTygvdrrWhnmvEjNLg=\ngithub.com/anchore/clio v0.0.0-20250715152405-a0fa658e5084/go.mod h1:42dWox8z4//b898OIELsQnSdYq9q1aCXkwp5fKF+BEU=\ngithub.com/anchore/fangs v0.0.0-20250716230140-94c22408c232 h1:aVC6r9h5wGNh8BYTW3CXxOdPoZzY/bBRWne1NvSTlO8=\ngithub.com/anchore/fangs v0.0.0-20250716230140-94c22408c232/go.mod h1:Zees1AEKNpXIRgdVAMYWITncarLFiPOtEQ7rl45V/h0=\ngithub.com/anchore/go-collections v0.0.0-20251016125210-a3c352120e8c h1:eoJXyC0n7DZ4YvySG/ETdYkTar2Due7eH+UmLK6FbrA=\ngithub.com/anchore/go-collections v0.0.0-20251016125210-a3c352120e8c/go.mod h1:1aiktV46ATCkuVg0O573ZrH56BUawTECPETbZyBcqT8=\ngithub.com/anchore/go-homedir v0.0.0-20250319154043-c29668562e4d h1:gT69osH9AsdpOfqxbRwtxcNnSZ1zg4aKy2BevO3ZBdc=\ngithub.com/anchore/go-homedir v0.0.0-20250319154043-c29668562e4d/go.mod h1:PhSnuFYknwPZkOWKB1jXBNToChBA+l0FjwOxtViIc50=\ngithub.com/anchore/go-logger v0.0.0-20250318195838-07ae343dd722 h1:2SqmFgE7h+Ql4VyBzhjLkRF/3gDrcpUBj8LjvvO6OOM=\ngithub.com/anchore/go-logger v0.0.0-20250318195838-07ae343dd722/go.mod h1:oFuE8YuTCM+spgMXhePGzk3asS94yO9biUfDzVTFqNw=\ngithub.com/anchore/go-lzo v0.1.0 h1:NgAacnzqPeGH49Ky19QKLBZEuFRqtTG9cdaucc3Vncs=\ngithub.com/anchore/go-lzo v0.1.0/go.mod h1:3kLx0bve2oN1iDwgM1U5zGku1Tfbdb0No5qp1eL1fIk=\ngithub.com/anchore/go-macholibre v0.0.0-20250320151634-807da7ad2331 h1:fWPHXkH3FQGVCyPkFMqNvMjQvdNMfkylBTsDqZC4lE4=\ngithub.com/anchore/go-macholibre v0.0.0-20250320151634-807da7ad2331/go.mod h1:DYvTRnWrlJ//6YOR83SiewmJiNFDEMRaOTnrzgco9FA=\ngithub.com/anchore/go-rpmdb v0.0.0-20250516171929-f77691e1faec h1:SjjPMOXTzpuU1ZME4XeoHyek+dry3/C7I8gzaCo02eg=\ngithub.com/anchore/go-rpmdb v0.0.0-20250516171929-f77691e1faec/go.mod h1:eQVa6QFGzKy0qMcnW2pez0XBczvgwSjw9vA23qifEyU=\ngithub.com/anchore/go-struct-converter v0.1.0 h1:2rDRssAl6mgKBSLNiVCMADgZRhoqtw9dedlWa0OhD30=\ngithub.com/anchore/go-struct-converter v0.1.0/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA=\ngithub.com/anchore/go-sync v0.0.0-20250714163430-add63db73ad1 h1:UK1SWZf2xD5jq8QVeDdpt6wW31cO3RckBvPmGlDrTkg=\ngithub.com/anchore/go-sync v0.0.0-20250714163430-add63db73ad1/go.mod h1:hd0Ol9qFM8tRDdF50a+DpZEoB0HFNaEnCp/BSVyBRlg=\ngithub.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 h1:rmZG77uXgE+o2gozGEBoUMpX27lsku+xrMwlmBZJtbg=\ngithub.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E=\ngithub.com/anchore/packageurl-go v0.1.1-0.20250220190351-d62adb6e1115 h1:ZyRCmiEjnoGJZ1+Ah0ZZ/mKKqNhGcUZBl0s7PTTDzvY=\ngithub.com/anchore/packageurl-go v0.1.1-0.20250220190351-d62adb6e1115/go.mod h1:KoYIv7tdP5+CC9VGkeZV4/vGCKsY55VvoG+5dadg4YI=\ngithub.com/anchore/stereoscope v0.1.22 h1:L807G/kk0WZzOCGuRGF7knxMKzwW2PGdbPVRystryd8=\ngithub.com/anchore/stereoscope v0.1.22/go.mod h1:FikPtAb/WnbqwgLHAvQA9O+fWez0K4pbjxzghz++iy4=\ngithub.com/anchore/syft v1.42.3 h1:eIeeGyqfXm/C8wpBWU50xFbOjdL37VbLatMj9nEJ6n4=\ngithub.com/anchore/syft v1.42.3/go.mod h1:i2PZ+276IdPcnd/n32aeIv849iO/QqdjRknbIc39yL0=\ngithub.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=\ngithub.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=\ngithub.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=\ngithub.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=\ngithub.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=\ngithub.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=\ngithub.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=\ngithub.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=\ngithub.com/aquasecurity/go-pep440-version v0.0.1 h1:8VKKQtH2aV61+0hovZS3T//rUF+6GDn18paFTVS0h0M=\ngithub.com/aquasecurity/go-pep440-version v0.0.1/go.mod h1:3naPe+Bp6wi3n4l5iBFCZgS0JG8vY6FT0H4NGhFJ+i4=\ngithub.com/aquasecurity/go-version v0.0.1 h1:4cNl516agK0TCn5F7mmYN+xVs1E3S45LkgZk3cbaW2E=\ngithub.com/aquasecurity/go-version v0.0.1/go.mod h1:s1UU6/v2hctXcOa3OLwfj5d9yoXHa3ahf+ipSwEvGT0=\ngithub.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=\ngithub.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=\ngithub.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=\ngithub.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\ngithub.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=\ngithub.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\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/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=\ngithub.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=\ngithub.com/aws/aws-sdk-go-v2 v1.41.2 h1:LuT2rzqNQsauaGkPK/7813XxcZ3o3yePY0Iy891T2ls=\ngithub.com/aws/aws-sdk-go-v2 v1.41.2/go.mod h1:IvvlAZQXvTXznUPfRVfryiG1fbzE2NGK6m9u39YQ+S4=\ngithub.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU=\ngithub.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4/go.mod h1:IOAPF6oT9KCsceNTvvYMNHy0+kMF8akOjeDvPENWxp4=\ngithub.com/aws/aws-sdk-go-v2/config v1.32.10 h1:9DMthfO6XWZYLfzZglAgW5Fyou2nRI5CuV44sTedKBI=\ngithub.com/aws/aws-sdk-go-v2/config v1.32.10/go.mod h1:2rUIOnA2JaiqYmSKYmRJlcMWy6qTj1vuRFscppSBMcw=\ngithub.com/aws/aws-sdk-go-v2/credentials v1.19.10 h1:EEhmEUFCE1Yhl7vDhNOI5OCL/iKMdkkYFTRpZXNw7m8=\ngithub.com/aws/aws-sdk-go-v2/credentials v1.19.10/go.mod h1:RnnlFCAlxQCkN2Q379B67USkBMu1PipEEiibzYN5UTE=\ngithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18 h1:Ii4s+Sq3yDfaMLpjrJsqD6SmG/Wq/P5L/hw2qa78UAY=\ngithub.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18/go.mod h1:6x81qnY++ovptLE6nWQeWrpXxbnlIex+4H4eYYGcqfc=\ngithub.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 h1:F43zk1vemYIqPAwhjTjYIz0irU2EY7sOb/F5eJ3HuyM=\ngithub.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18/go.mod h1:w1jdlZXrGKaJcNoL+Nnrj+k5wlpGXqnNrKoP22HvAug=\ngithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 h1:xCeWVjj0ki0l3nruoyP2slHsGArMxeiiaoPN5QZH6YQ=\ngithub.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18/go.mod h1:r/eLGuGCBw6l36ZRWiw6PaZwPXb6YOj+i/7MizNl5/k=\ngithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=\ngithub.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=\ngithub.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17 h1:JqcdRG//czea7Ppjb+g/n4o8i/R50aTBHkA7vu0lK+k=\ngithub.com/aws/aws-sdk-go-v2/internal/v4a v1.4.17/go.mod h1:CO+WeGmIdj/MlPel2KwID9Gt7CNq4M65HUfBW97liM0=\ngithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 h1:CeY9LUdur+Dxoeldqoun6y4WtJ3RQtzk0JMP2gfUay0=\ngithub.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5/go.mod h1:AZLZf2fMaahW5s/wMRciu1sYbdsikT/UHwbUjOdEVTc=\ngithub.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8 h1:Z5EiPIzXKewUQK0QTMkutjiaPVeVYXX7KIqhXu/0fXs=\ngithub.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.8/go.mod h1:FsTpJtvC4U1fyDXk7c71XoDv3HlRm8V3NiYLeYLh5YE=\ngithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 h1:LTRCYFlnnKFlKsyIQxKhJuDuA3ZkrDQMRYm6rXiHlLY=\ngithub.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18/go.mod h1:XhwkgGG6bHSd00nO/mexWTcTjgd6PjuvWQMqSn2UaEk=\ngithub.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17 h1:bGeHBsGZx0Dvu/eJC0Lh9adJa3M1xREcndxLNZlve2U=\ngithub.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.17/go.mod h1:dcW24lbU0CzHusTE8LLHhRLI42ejmINN8Lcr22bwh/g=\ngithub.com/aws/aws-sdk-go-v2/service/s3 v1.96.0 h1:oeu8VPlOre74lBA/PMhxa5vewaMIMmILM+RraSyB8KA=\ngithub.com/aws/aws-sdk-go-v2/service/s3 v1.96.0/go.mod h1:5jggDlZ2CLQhwJBiZJb4vfk4f0GxWdEDruWKEJ1xOdo=\ngithub.com/aws/aws-sdk-go-v2/service/signin v1.0.6 h1:MzORe+J94I+hYu2a6XmV5yC9huoTv8NRcCrUNedDypQ=\ngithub.com/aws/aws-sdk-go-v2/service/signin v1.0.6/go.mod h1:hXzcHLARD7GeWnifd8j9RWqtfIgxj4/cAtIVIK7hg8g=\ngithub.com/aws/aws-sdk-go-v2/service/sso v1.30.11 h1:7oGD8KPfBOJGXiCoRKrrrQkbvCp8N++u36hrLMPey6o=\ngithub.com/aws/aws-sdk-go-v2/service/sso v1.30.11/go.mod h1:0DO9B5EUJQlIDif+XJRWCljZRKsAFKh3gpFz7UnDtOo=\ngithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15 h1:edCcNp9eGIUDUCrzoCu1jWAXLGFIizeqkdkKgRlJwWc=\ngithub.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15/go.mod h1:lyRQKED9xWfgkYC/wmmYfv7iVIM68Z5OQ88ZdcV1QbU=\ngithub.com/aws/aws-sdk-go-v2/service/sts v1.41.7 h1:NITQpgo9A5NrDZ57uOWj+abvXSb83BbyggcUBVksN7c=\ngithub.com/aws/aws-sdk-go-v2/service/sts v1.41.7/go.mod h1:sks5UWBhEuWYDPdwlnRFn1w7xWdH29Jcpe+/PJQefEs=\ngithub.com/aws/smithy-go v1.24.1 h1:VbyeNfmYkWoxMVpGUAbQumkODcYmfMRfZ8yQiH30SK0=\ngithub.com/aws/smithy-go v1.24.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=\ngithub.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=\ngithub.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=\ngithub.com/becheran/wildmatch-go v1.0.0 h1:mE3dGGkTmpKtT4Z+88t8RStG40yN9T+kFEGj2PZFSzA=\ngithub.com/becheran/wildmatch-go v1.0.0/go.mod h1:gbMvj0NtVdJ15Mg/mH9uxk2R1QCistMyU7d9KFzroX4=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=\ngithub.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=\ngithub.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=\ngithub.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=\ngithub.com/bitnami/go-version v0.0.0-20250505154626-452e8c5ee607 h1:lBg3tHGquFySSblLi9zNi2iGNmVLRHBzVal2fqphCM8=\ngithub.com/bitnami/go-version v0.0.0-20250505154626-452e8c5ee607/go.mod h1:9iglf1GG4oNRJ39bZ5AZrjgAFD2RwQbXw6Qf7Cs47wo=\ngithub.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=\ngithub.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=\ngithub.com/bmatcuk/doublestar/v4 v4.10.0 h1:zU9WiOla1YA122oLM6i4EXvGW62DvKZVxIe6TYWexEs=\ngithub.com/bmatcuk/doublestar/v4 v4.10.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=\ngithub.com/bodgit/plumbing v1.3.0 h1:pf9Itz1JOQgn7vEOE7v7nlEfBykYqvUYioC61TwWCFU=\ngithub.com/bodgit/plumbing v1.3.0/go.mod h1:JOTb4XiRu5xfnmdnDJo6GmSbSbtSyufrsyZFByMtKEs=\ngithub.com/bodgit/sevenzip v1.6.1 h1:kikg2pUMYC9ljU7W9SaqHXhym5HyKm8/M/jd31fYan4=\ngithub.com/bodgit/sevenzip v1.6.1/go.mod h1:GVoYQbEVbOGT8n2pfqCIMRUaRjQ8F9oSqoBEqZh5fQ8=\ngithub.com/bodgit/windows v1.0.1 h1:tF7K6KOluPYygXa3Z2594zxlkbKPAOvqr97etrGNIz4=\ngithub.com/bodgit/windows v1.0.1/go.mod h1:a6JLwrB4KrTR5hBpp8FI9/9W9jJfeQ2h4XDXU74ZCdM=\ngithub.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=\ngithub.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\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/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5fXonfvc=\ngithub.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E=\ngithub.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=\ngithub.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=\ngithub.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk=\ngithub.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk=\ngithub.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=\ngithub.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=\ngithub.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=\ngithub.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=\ngithub.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8=\ngithub.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ=\ngithub.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI=\ngithub.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q=\ngithub.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=\ngithub.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=\ngithub.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=\ngithub.com/chromedp/chromedp v0.9.2/go.mod h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs=\ngithub.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=\ngithub.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=\ngithub.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/clipperhouse/displaywidth v0.10.0 h1:GhBG8WuerxjFQQYeuZAeVTuyxuX+UraiZGD4HJQ3Y8g=\ngithub.com/clipperhouse/displaywidth v0.10.0/go.mod h1:XqJajYsaiEwkxOj4bowCTMcT1SgvHo9flfF3jQasdbs=\ngithub.com/clipperhouse/uax29/v2 v2.6.0 h1:z0cDbUV+aPASdFb2/ndFnS9ts/WNXgTNNGFoKXuhpos=\ngithub.com/clipperhouse/uax29/v2 v2.6.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=\ngithub.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=\ngithub.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w=\ngithub.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI=\ngithub.com/containerd/cgroups/v3 v3.1.2 h1:OSosXMtkhI6Qove637tg1XgK4q+DhR0mX8Wi8EhrHa4=\ngithub.com/containerd/cgroups/v3 v3.1.2/go.mod h1:PKZ2AcWmSBsY/tJUVhtS/rluX0b1uq1GmPO1ElCmbOw=\ngithub.com/containerd/containerd/api v1.10.0 h1:5n0oHYVBwN4VhoX9fFykCV9dF1/BvAXeg2F8W6UYq1o=\ngithub.com/containerd/containerd/api v1.10.0/go.mod h1:NBm1OAk8ZL+LG8R0ceObGxT5hbUYj7CzTmR3xh0DlMM=\ngithub.com/containerd/containerd/v2 v2.2.1 h1:TpyxcY4AL5A+07dxETevunVS5zxqzuq7ZqJXknM11yk=\ngithub.com/containerd/containerd/v2 v2.2.1/go.mod h1:NR70yW1iDxe84F2iFWbR9xfAN0N2F0NcjTi1OVth4nU=\ngithub.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4=\ngithub.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=\ngithub.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=\ngithub.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=\ngithub.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=\ngithub.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=\ngithub.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY=\ngithub.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o=\ngithub.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=\ngithub.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=\ngithub.com/containerd/platforms v1.0.0-rc.2 h1:0SPgaNZPVWGEi4grZdV8VRYQn78y+nm6acgLGv/QzE4=\ngithub.com/containerd/platforms v1.0.0-rc.2/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4=\ngithub.com/containerd/plugin v1.0.0 h1:c8Kf1TNl6+e2TtMHZt+39yAPDbouRH9WAToRjex483Y=\ngithub.com/containerd/plugin v1.0.0/go.mod h1:hQfJe5nmWfImiqT1q8Si3jLv3ynMUIBB47bQ+KexvO8=\ngithub.com/containerd/stargz-snapshotter/estargz v0.18.2 h1:yXkZFYIzz3eoLwlTUZKz2iQ4MrckBxJjkmD16ynUTrw=\ngithub.com/containerd/stargz-snapshotter/estargz v0.18.2/go.mod h1:XyVU5tcJ3PRpkA9XS2T5us6Eg35yM0214Y+wvrZTBrY=\ngithub.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRqQ=\ngithub.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=\ngithub.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=\ngithub.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=\ngithub.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=\ngithub.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is=\ngithub.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=\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/deitch/magic v0.0.0-20240306090643-c67ab88f10cb h1:4W/2rQ3wzEimF5s+J6OY3ODiQtJZ5W1sForSgogVXkY=\ngithub.com/deitch/magic v0.0.0-20240306090643-c67ab88f10cb/go.mod h1:B3tI9iGHi4imdLi4Asdha1Sc6feLMTfPLXh9IUYmysk=\ngithub.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4=\ngithub.com/diskfs/go-diskfs v1.7.0 h1:vonWmt5CMowXwUc79jWyGrf2DIMeoOjkLlMnQYGVOs8=\ngithub.com/diskfs/go-diskfs v1.7.0/go.mod h1:LhQyXqOugWFRahYUSw47NyZJPezFzB9UELwhpszLP/k=\ngithub.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=\ngithub.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=\ngithub.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c=\ngithub.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0=\ngithub.com/docker/cli v29.3.0+incompatible h1:z3iWveU7h19Pqx7alZES8j+IeFQZ1lhTwb2F+V9SVvk=\ngithub.com/docker/cli v29.3.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=\ngithub.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=\ngithub.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=\ngithub.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY=\ngithub.com/docker/docker-credential-helpers v0.9.5/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c=\ngithub.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=\ngithub.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=\ngithub.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=\ngithub.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=\ngithub.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 h1:2tV76y6Q9BB+NEBasnqvs7e49aEBFI8ejC89PSnWH+4=\ngithub.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=\ngithub.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=\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/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=\ngithub.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=\ngithub.com/elliotchance/phpserialize v1.4.0 h1:cAp/9+KSnEbUC8oYCE32n2n84BeW8HOY3HMDI8hG2OY=\ngithub.com/elliotchance/phpserialize v1.4.0/go.mod h1:gt7XX9+ETUcLXbtTKEuyrqW3lcLUAeS/AnGZ2e49TZs=\ngithub.com/elliotwutingfeng/asciiset v0.0.0-20230602022725-51bbb787efab h1:h1UgjJdAAhj+uPL68n7XASS6bU+07ZX1WJvVS2eyoeY=\ngithub.com/elliotwutingfeng/asciiset v0.0.0-20230602022725-51bbb787efab/go.mod h1:GLo/8fDswSAniFG+BFIaiSPcK610jyzgEhWYPQwuQdw=\ngithub.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=\ngithub.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=\ngithub.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=\ngithub.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA=\ngithub.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU=\ngithub.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g=\ngithub.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98=\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 v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=\ngithub.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4=\ngithub.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA=\ngithub.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=\ngithub.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=\ngithub.com/facebookincubator/flog v0.0.0-20190930132826-d2511d0ce33c/go.mod h1:QGzNH9ujQ2ZUr/CjDGZGWeDAVStrWNjHeEcjJL96Nuk=\ngithub.com/facebookincubator/nvdtools v0.1.5 h1:jbmDT1nd6+k+rlvKhnkgMokrCAzHoASWE5LtHbX2qFQ=\ngithub.com/facebookincubator/nvdtools v0.1.5/go.mod h1:Kh55SAWnjckS96TBSrXI99KrEKH4iB0OJby3N8GRJO4=\ngithub.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=\ngithub.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=\ngithub.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=\ngithub.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=\ngithub.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=\ngithub.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA=\ngithub.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI=\ngithub.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=\ngithub.com/felixge/fgprof v0.9.5 h1:8+vR6yu2vvSKn08urWyEuxx75NWPEvybbkBirEpsbVY=\ngithub.com/felixge/fgprof v0.9.5/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM=\ngithub.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=\ngithub.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=\ngithub.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=\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/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=\ngithub.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/github/go-spdx/v2 v2.4.0 h1:+4IwVwJJbm3rzvrQ6P1nI9BDMcy3la4RchRy5uehV/M=\ngithub.com/github/go-spdx/v2 v2.4.0/go.mod h1:/5rwgS0txhGtRdUZwc02bTglzg6HK3FfuEbECKlK2Sg=\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-snaps v0.5.20 h1:FGKonEeQPJ12t7RQj6cTPa881fl5c8HYarMLv5vP7sg=\ngithub.com/gkampitakis/go-snaps v0.5.20/go.mod h1:gC3YqxQTPyIXvQrw/Vpt3a8VqR1MO8sVpZFWN4DGwNs=\ngithub.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=\ngithub.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=\ngithub.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=\ngithub.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=\ngithub.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=\ngithub.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=\ngithub.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDzZG0=\ngithub.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY=\ngithub.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=\ngithub.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=\ngithub.com/go-git/go-git/v5 v5.17.0 h1:AbyI4xf+7DsjINHMu35quAh4wJygKBKBuXVjV/pxesM=\ngithub.com/go-git/go-git/v5 v5.17.0/go.mod h1:f82C4YiLx+Lhi8eHxltLeGC5uBTXSFa6PC5WW9o4SjI=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=\ngithub.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\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-restruct/restruct v1.2.0-alpha h1:2Lp474S/9660+SJjpVxoKuWX09JsXHSrdV7Nv3/gkvc=\ngithub.com/go-restruct/restruct v1.2.0-alpha/go.mod h1:KqrpKpn4M8OLznErihXTGLlsXFGeLxHUrLRRI/1YjGk=\ngithub.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=\ngithub.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=\ngithub.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=\ngithub.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=\ngithub.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=\ngithub.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=\ngithub.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=\ngithub.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=\ngithub.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=\ngithub.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=\ngithub.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=\ngithub.com/gohugoio/hashstructure v0.6.0 h1:7wMB/2CfXoThFYhdWRGv3u3rUM761Cq29CxUW+NltUg=\ngithub.com/gohugoio/hashstructure v0.6.0/go.mod h1:lapVLk9XidheHG1IQ4ZSbyYrXcaILU1ZEP/+vno5rBQ=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=\ngithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=\ngithub.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786 h1:rcv+Ippz6RAtvaGgKxc+8FQIpxHgsF+HBzPyYL2cyVU=\ngithub.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786/go.mod h1:apVn/GCasLZUVpAJ6oWAuyP7Ne7CEsQbTnc0plM3m+o=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\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/go-containerregistry v0.21.2 h1:vYaMU4nU55JJGFC9JR/s8NZcTjbE9DBBbvusTW9NeS0=\ngithub.com/google/go-containerregistry v0.21.2/go.mod h1:ctO5aCaewH4AK1AumSF5DPW+0+R+d2FmylMJdp5G7p0=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/licensecheck v0.3.1 h1:QoxgoDkaeC4nFrtGN1jV7IPmDCHFNIVh54e5hSt6sPs=\ngithub.com/google/licensecheck v0.3.1/go.mod h1:ORkR35t/JjW+emNKtfJDII0zlciG9JgbT7SmsohlHmY=\ngithub.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=\ngithub.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc=\ngithub.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=\ngithub.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=\ngithub.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5 h1:xhMrHhTJ6zxu3gA4enFM9MLn9AY7613teCdFnlUVbSQ=\ngithub.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=\ngithub.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=\ngithub.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=\ngithub.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\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/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao=\ngithub.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=\ngithub.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=\ngithub.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc=\ngithub.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY=\ngithub.com/gookit/assert v0.1.1 h1:lh3GcawXe/p+cU7ESTZ5Ui3Sm/x8JWpIis4/1aF0mY0=\ngithub.com/gookit/assert v0.1.1/go.mod h1:jS5bmIVQZTIwk42uXl4lyj4iaaxx32tqH16CFj0VX2E=\ngithub.com/gookit/color v1.2.5/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg=\ngithub.com/gookit/color v1.6.0 h1:JjJXBTk1ETNyqyilJhkTXJYYigHG24TM9Xa2M1xAhRA=\ngithub.com/gookit/color v1.6.0/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs=\ngithub.com/gpustack/gguf-parser-go v0.24.0 h1:tdJceXYp9e5RhE9RwVYIuUpir72Jz2D68NEtDXkKCKc=\ngithub.com/gpustack/gguf-parser-go v0.24.0/go.mod h1:y4TwTtDqFWTK+xvprOjRUh+dowgU2TKCX37vRKvGiZ0=\ngithub.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=\ngithub.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.70 h1:0HADrxxqaQkGycO1JoUUA+B4FnIkuo8d2bz/hSaTFFQ=\ngithub.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.70/go.mod h1:fm2FdDCzJdtbXF7WKAMvBb5NEPouXPHFbGNYs9ShFns=\ngithub.com/hashicorp/cli v1.1.7 h1:/fZJ+hNdwfTSfsxMBa9WWMlfjUZbX8/LnUxgAd7lCVU=\ngithub.com/hashicorp/cli v1.1.7/go.mod h1:e6Mfpga9OCT1vqzFuoGZiiF/KaG9CbUfO5s3ghU3YgU=\ngithub.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=\ngithub.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=\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-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU=\ngithub.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=\ngithub.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=\ngithub.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=\ngithub.com/hashicorp/go-getter v1.8.5 h1:DMPV5CSw5JrNg/IK7kDZt3+l2REKXOi3oAw7uYLh2NM=\ngithub.com/hashicorp/go-getter v1.8.5/go.mod h1:WIffejwAyDSJhoVptc3UEshEMkR9O63rw34V7k43O3Q=\ngithub.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=\ngithub.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=\ngithub.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=\ngithub.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=\ngithub.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=\ngithub.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=\ngithub.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=\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/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=\ngithub.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=\ngithub.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=\ngithub.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=\ngithub.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=\ngithub.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=\ngithub.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=\ngithub.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=\ngithub.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=\ngithub.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=\ngithub.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=\ngithub.com/hashicorp/hc-install v0.9.2 h1:v80EtNX4fCVHqzL9Lg/2xkp62bbvQMnvPQ0G+OmtO24=\ngithub.com/hashicorp/hc-install v0.9.2/go.mod h1:XUqBQNnuT4RsxoxiM9ZaUk0NX8hi2h+Lb6/c0OZnC/I=\ngithub.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=\ngithub.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE=\ngithub.com/hashicorp/hcl/v2 v2.24.0/go.mod h1:oGoO1FIQYfn/AgyOhlg9qLC6/nOJPX3qGbkZpYAcqfM=\ngithub.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=\ngithub.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=\ngithub.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=\ngithub.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=\ngithub.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=\ngithub.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=\ngithub.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=\ngithub.com/hashicorp/terraform-exec v0.24.0 h1:mL0xlk9H5g2bn0pPF6JQZk5YlByqSqrO5VoaNtAf8OE=\ngithub.com/hashicorp/terraform-exec v0.24.0/go.mod h1:lluc/rDYfAhYdslLJQg3J0oDqo88oGQAdHR+wDqFvo4=\ngithub.com/hashicorp/terraform-json v0.27.2 h1:BwGuzM6iUPqf9JYM/Z4AF1OJ5VVJEEzoKST/tRDBJKU=\ngithub.com/hashicorp/terraform-json v0.27.2/go.mod h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE=\ngithub.com/hashicorp/terraform-plugin-docs v0.24.0 h1:YNZYd+8cpYclQyXbl1EEngbld8w7/LPOm99GD5nikIU=\ngithub.com/hashicorp/terraform-plugin-docs v0.24.0/go.mod h1:YLg+7LEwVmRuJc0EuCw0SPLxuQXw5mW8iJ5ml/kvi+o=\ngithub.com/henvic/httpretty v0.1.4 h1:Jo7uwIRWVFxkqOnErcoYfH90o3ddQyVrSANeS4cxYmU=\ngithub.com/henvic/httpretty v0.1.4/go.mod h1:Dn60sQTZfbt2dYsdUSNsCljyF4AfdqnuJFDLJA1I4AM=\ngithub.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=\ngithub.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=\ngithub.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=\ngithub.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=\ngithub.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=\ngithub.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=\ngithub.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=\ngithub.com/jedib0t/go-pretty/v6 v6.7.8 h1:BVYrDy5DPBA3Qn9ICT+PokP9cvCv1KaHv2i+Hc8sr5o=\ngithub.com/jedib0t/go-pretty/v6 v6.7.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU=\ngithub.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=\ngithub.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=\ngithub.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953 h1:WdAeg/imY2JFPc/9CST4bZ80nNJbiBFCAdSZCSgrS5Y=\ngithub.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953/go.mod h1:6o+UrvuZWc4UTyBhQf0LGjW9Ld7qJxLz/OqvSOWWlEc=\ngithub.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=\ngithub.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=\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.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=\ngithub.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=\ngithub.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=\ngithub.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=\ngithub.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=\ngithub.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.2.0/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/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=\ngithub.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=\ngithub.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=\ngithub.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=\ngithub.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=\ngithub.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=\ngithub.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=\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/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=\ngithub.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=\ngithub.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=\ngithub.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=\ngithub.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=\ngithub.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=\ngithub.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=\ngithub.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=\ngithub.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75 h1:P8UmIzZMYDR+NGImiFvErt6VWfIRPuGM+vyjiEdkmIw=\ngithub.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=\ngithub.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=\ngithub.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=\ngithub.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=\ngithub.com/mholt/archives v0.1.5 h1:Fh2hl1j7VEhc6DZs2DLMgiBNChUux154a1G+2esNvzQ=\ngithub.com/mholt/archives v0.1.5/go.mod h1:3TPMmBLPsgszL+1As5zECTuKwKvIfj6YcwWPpeTAXF4=\ngithub.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=\ngithub.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=\ngithub.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=\ngithub.com/mikelolasagasti/xz v1.0.1 h1:Q2F2jX0RYJUG3+WsM+FJknv+6eVjsjXNDV0KJXZzkD0=\ngithub.com/mikelolasagasti/xz v1.0.1/go.mod h1:muAirjiOUxPRXwm9HdDtB3uoRPrGnL85XHtokL9Hcgc=\ngithub.com/minio/minlz v1.0.1 h1:OUZUzXcib8diiX+JYxyRLIdomyZYzHct6EShOKtQY2A=\ngithub.com/minio/minlz v1.0.1/go.mod h1:qT0aEB35q79LLornSzeDH75LBf3aH1MV+jB5w9Wasec=\ngithub.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=\ngithub.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=\ngithub.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=\ngithub.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=\ngithub.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=\ngithub.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=\ngithub.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=\ngithub.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=\ngithub.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=\ngithub.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=\ngithub.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=\ngithub.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=\ngithub.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=\ngithub.com/moby/moby/api v1.54.0 h1:7kbUgyiKcoBhm0UrWbdrMs7RX8dnwzURKVbZGy2GnL0=\ngithub.com/moby/moby/api v1.54.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=\ngithub.com/moby/moby/client v0.3.0 h1:UUGL5okry+Aomj3WhGt9Aigl3ZOxZGqR7XPo+RLPlKs=\ngithub.com/moby/moby/client v0.3.0/go.mod h1:HJgFbJRvogDQjbM8fqc1MCEm4mIAGMLjXbgwoZp6jCQ=\ngithub.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=\ngithub.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=\ngithub.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=\ngithub.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=\ngithub.com/moby/sys/signal v0.7.1 h1:PrQxdvxcGijdo6UXXo/lU/TvHUWyPhj7UOpSo8tuvk0=\ngithub.com/moby/sys/signal v0.7.1/go.mod h1:Se1VGehYokAkrSQwL4tDzHvETwUZlnY7S5XtQ50mQp8=\ngithub.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=\ngithub.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=\ngithub.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=\ngithub.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=\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 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\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/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=\ngithub.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=\ngithub.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=\ngithub.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=\ngithub.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=\ngithub.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=\ngithub.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=\ngithub.com/nix-community/go-nix v0.0.0-20250101154619-4bdde671e0a1 h1:kpt9ZfKcm+EDG4s40hMwE//d5SBgDjUOrITReV2u4aA=\ngithub.com/nix-community/go-nix v0.0.0-20250101154619-4bdde671e0a1/go.mod h1:qgCw4bBKZX8qMgGeEZzGFVT3notl42dBjNqO2jut0M0=\ngithub.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE=\ngithub.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8=\ngithub.com/nwaples/rardecode/v2 v2.2.0 h1:4ufPGHiNe1rYJxYfehALLjup4Ls3ck42CWwjKiOqu0A=\ngithub.com/nwaples/rardecode/v2 v2.2.0/go.mod h1:7uz379lSxPe6j9nvzxUZ+n7mnJNgjsRNb6IbvGVHRmw=\ngithub.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj4EljqMiZsIcE09mmF8XsD5AYOJc=\ngithub.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=\ngithub.com/olekukonko/errors v1.2.0 h1:10Zcn4GeV59t/EGqJc8fUjtFT/FuUh5bTMzZ1XwmCRo=\ngithub.com/olekukonko/errors v1.2.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=\ngithub.com/olekukonko/ll v0.1.6 h1:lGVTHO+Qc4Qm+fce/2h2m5y9LvqaW+DCN7xW9hsU3uA=\ngithub.com/olekukonko/ll v0.1.6/go.mod h1:NVUmjBb/aCtUpjKk75BhWrOlARz3dqsM+OtszpY4o88=\ngithub.com/olekukonko/tablewriter v1.1.4 h1:ORUMI3dXbMnRlRggJX3+q7OzQFDdvgbN9nVWj1drm6I=\ngithub.com/olekukonko/tablewriter v1.1.4/go.mod h1:+kedxuyTtgoZLwif3P1Em4hARJs+mVnzKxmsCL/C5RY=\ngithub.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=\ngithub.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=\ngithub.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=\ngithub.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=\ngithub.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=\ngithub.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=\ngithub.com/opencontainers/runtime-spec v1.3.0 h1:YZupQUdctfhpZy3TM39nN9Ika5CBWT5diQ8ibYCRkxg=\ngithub.com/opencontainers/runtime-spec v1.3.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=\ngithub.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE=\ngithub.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg=\ngithub.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=\ngithub.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=\ngithub.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=\ngithub.com/pborman/indent v1.2.1 h1:lFiviAbISHv3Rf0jcuh489bi06hj98JsVMtIDZQb9yM=\ngithub.com/pborman/indent v1.2.1/go.mod h1:FitS+t35kIYtB5xWTZAPhnmrxcciEEOdbyrrpz5K6Vw=\ngithub.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=\ngithub.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=\ngithub.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=\ngithub.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=\ngithub.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=\ngithub.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=\ngithub.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=\ngithub.com/pjbgf/sha1cd v0.4.0 h1:NXzbL1RvjTUi6kgYZCX3fPwwl27Q1LJndxtUDVfJGRY=\ngithub.com/pjbgf/sha1cd v0.4.0/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=\ngithub.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=\ngithub.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=\ngithub.com/pkg/xattr v0.4.12 h1:rRTkSyFNTRElv6pkA3zpjHpQ90p/OdHQC1GmGh1aTjM=\ngithub.com/pkg/xattr v0.4.12/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU=\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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=\ngithub.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=\ngithub.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=\ngithub.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=\ngithub.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=\ngithub.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=\ngithub.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=\ngithub.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=\ngithub.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=\ngithub.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/rust-secure-code/go-rustaudit v0.0.0-20250226111315-e20ec32e963c h1:8gOLsYwaY2JwlTMT4brS5/9XJdrdIbmk2obvQ748CC0=\ngithub.com/rust-secure-code/go-rustaudit v0.0.0-20250226111315-e20ec32e963c/go.mod h1:kwM/7r/rVluTE8qJbHAffduuqmSv4knVQT2IajGvSiA=\ngithub.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=\ngithub.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=\ngithub.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=\ngithub.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=\ngithub.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=\ngithub.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=\ngithub.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=\ngithub.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=\ngithub.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=\ngithub.com/sanity-io/litter v1.5.8 h1:uM/2lKrWdGbRXDrIq08Lh9XtVYoeGtcQxk9rtQ7+rYg=\ngithub.com/sanity-io/litter v1.5.8/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U=\ngithub.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg=\ngithub.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI=\ngithub.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e h1:7q6NSFZDeGfvvtIRwBrU/aegEYJYmvev0cHAwo17zZQ=\ngithub.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs=\ngithub.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=\ngithub.com/sebdah/goldie v1.0.0 h1:9GNhIat69MSlz/ndaBg48vl9dF5fI+NBB6kfOxgfkMc=\ngithub.com/sebdah/goldie/v2 v2.8.0 h1:dZb9wR8q5++oplmEiJT+U/5KyotVD+HNGCAc5gNr8rc=\ngithub.com/sebdah/goldie/v2 v2.8.0/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=\ngithub.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=\ngithub.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=\ngithub.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=\ngithub.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=\ngithub.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=\ngithub.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=\ngithub.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=\ngithub.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=\ngithub.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=\ngithub.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=\ngithub.com/smallnest/ringbuffer v0.0.0-20241116012123-461381446e3d h1:3VwvTjiRPA7cqtgOWddEL+JrcijMlXUmj99c/6YyZoY=\ngithub.com/smallnest/ringbuffer v0.0.0-20241116012123-461381446e3d/go.mod h1:tAG61zBM1DYRaGIPloumExGvScf08oHuo0kFoOqdbT0=\ngithub.com/sorairolake/lzip-go v0.3.8 h1:j5Q2313INdTA80ureWYRhX+1K78mUXfMoPZCw/ivWik=\ngithub.com/sorairolake/lzip-go v0.3.8/go.mod h1:JcBqGMV0frlxwrsE9sMWXDjqn3EeVf0/54YPsw66qkU=\ngithub.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=\ngithub.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/spdx/gordf v0.0.0-20250128162952-000978ccd6fb h1:7G2Czq97VORM5xNRrD8tSQdhoXPRs8s+Otlc7st9TS0=\ngithub.com/spdx/gordf v0.0.0-20250128162952-000978ccd6fb/go.mod h1:uKWaldnbMnjsSAXRurWqqrdyZen1R7kxl8TkmWk2OyM=\ngithub.com/spdx/tools-golang v0.5.7 h1:+sWcKGnhwp3vLdMqPcLdA6QK679vd86cK9hQWH3AwCg=\ngithub.com/spdx/tools-golang v0.5.7/go.mod h1:jg7w0LOpoNAw6OxKEzCoqPC2GCTj45LyTlVmXubDsYw=\ngithub.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=\ngithub.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=\ngithub.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=\ngithub.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=\ngithub.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=\ngithub.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=\ngithub.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=\ngithub.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=\ngithub.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=\ngithub.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=\ngithub.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=\ngithub.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\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/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=\ngithub.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=\ngithub.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=\ngithub.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo=\ngithub.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/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.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\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/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=\ngithub.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=\ngithub.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=\ngithub.com/sylabs/sif/v2 v2.24.0 h1:1wB5uMDUQYjk8AckTySaDcP9YnpMb1LyDRr1Jt9A10w=\ngithub.com/sylabs/sif/v2 v2.24.0/go.mod h1:DbXWqWZ1hdLSU+K9ipdds5AmZeHWsyxCOj/oQakBa88=\ngithub.com/sylabs/squashfs v1.0.6 h1:PvJcDzxr+vIm2kH56mEMbaOzvGu79gK7P7IX+R7BDZI=\ngithub.com/sylabs/squashfs v1.0.6/go.mod h1:DlDeUawVXLWAsSRa085Eo0ZenGzAB32JdAUFaB0LZfE=\ngithub.com/terminalstatic/go-xsd-validate v0.1.6 h1:TenYeQ3eY631qNi1/cTmLH/s2slHPRKTTHT+XSHkepo=\ngithub.com/terminalstatic/go-xsd-validate v0.1.6/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw=\ngithub.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw=\ngithub.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY=\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/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=\ngithub.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=\ngithub.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=\ngithub.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=\ngithub.com/vbatts/go-mtree v0.7.0 h1:ytmOc3MTRidZiBi9VBCyZ2BHe4fZS47L5v7BVXDWW4E=\ngithub.com/vbatts/go-mtree v0.7.0/go.mod h1:EjdpFC+LZy1TXbRGNa1MKKgjQ+7ew3foMFJK8o4/TdY=\ngithub.com/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4=\ngithub.com/vbatts/tar-split v0.12.2/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=\ngithub.com/vifraa/gopom v1.0.0 h1:L9XlKbyvid8PAIK8nr0lihMApJQg/12OBvMA28BcWh0=\ngithub.com/vifraa/gopom v1.0.0/go.mod h1:oPa1dcrGrtlO37WPDBm5SqHAT+wTgF8An1Q71Z6Vv4o=\ngithub.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651 h1:jIVmlAFIqV3d+DOxazTR9v+zgj8+VYuQBzPgBZvWBHA=\ngithub.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651/go.mod h1:b26F2tHLqaoRQf8DywqzVaV1MQ9yvjb0OMcNl7Nxu20=\ngithub.com/wagoodman/go-progress v0.0.0-20260303201901-10176f79b2c0 h1:EHsPe0Q0ANoLOZff1dBLAyeWLTA4sbPTpGI+2zb0FnM=\ngithub.com/wagoodman/go-progress v0.0.0-20260303201901-10176f79b2c0/go.mod h1:g/D9uEUFp5YLyciwCpVsSOZOm56hfv4rzGJod6MlqIM=\ngithub.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=\ngithub.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=\ngithub.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=\ngithub.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=\ngithub.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=\ngithub.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=\ngithub.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=\ngithub.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=\ngithub.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=\ngithub.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=\ngithub.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=\ngithub.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngithub.com/yuin/goldmark v1.7.7 h1:5m9rrB1sW3JUMToKFQfb+FGt1U7r57IHu5GrYrG2nqU=\ngithub.com/yuin/goldmark v1.7.7/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=\ngithub.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=\ngithub.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=\ngithub.com/zclconf/go-cty v1.17.0 h1:seZvECve6XX4tmnvRzWtJNHdscMtYEx5R7bnnVyd/d0=\ngithub.com/zclconf/go-cty v1.17.0/go.mod h1:wqFzcImaLTI6A5HfsRwB0nj5n0MRZFwmey8YoFPPs3U=\ngithub.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=\ngithub.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=\ngithub.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1 h1:V+UsotZpAVvfj3X/LMoEytoLzSiP6Lg0F7wdVyu9gGg=\ngithub.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1/go.mod h1:ly2RBz4mnz1yeuVbQA/VFwGjK3mnHGRj1JuoG336Bis=\ngo.abhg.dev/goldmark/frontmatter v0.2.0 h1:P8kPG0YkL12+aYk2yU3xHv4tcXzeVnN+gU0tJ5JnxRw=\ngo.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px76YjkOzhB4YlU=\ngo.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=\ngo.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=\ngo.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=\ngo.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=\ngo.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=\ngo.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=\ngo.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=\ngo.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=\ngo.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE=\ngo.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo=\ngo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY=\ngo.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=\ngo.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=\ngo.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 h1:5gn2urDL/FBnK8OkCfD1j3/ER79rUuTYmCvlXBKeYL8=\ngo.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0/go.mod h1:0fBG6ZJxhqByfFZDwSwpZGzJU671HkwpWaNe2t4VUPI=\ngo.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=\ngo.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=\ngo.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=\ngo.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE=\ngo.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw=\ngo.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg=\ngo.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=\ngo.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=\ngo.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=\ngo.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=\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.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=\ngo.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=\ngo.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=\ngo.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=\ngo4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc=\ngo4.org v0.0.0-20230225012048-214862532bf5/go.mod h1:F57wTi5Lrj6WLyswp5EYV1ncrEbFGHD4hhz6S1ZYeaU=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=\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/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=\ngolang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=\ngolang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY=\ngolang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\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.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=\ngolang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=\ngolang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=\ngolang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=\ngolang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=\ngolang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=\ngolang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=\ngolang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=\ngolang.org/x/telemetry v0.0.0-20260311193753-579e4da9a98c h1:6a8FdnNk6bTXBjR4AGKFgUKuo+7GnR3FX5L7CbveeZc=\ngolang.org/x/telemetry v0.0.0-20260311193753-579e4da9a98c/go.mod h1:TpUTTEp9frx7rTdLpC9gFG9kdI7zVLFTFFlqaH2Cncw=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=\ngolang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=\ngolang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=\ngolang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=\ngolang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=\ngolang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=\ngolang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=\ngolang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM=\ngolang.org/x/tools/go/expect v0.1.1-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/vuln v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I=\ngolang.org/x/vuln v1.1.4/go.mod h1:F+45wmU18ym/ca5PLTPLsSzr2KppzswxPP603ldA67s=\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=\ngolang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=\ngolang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=\ngonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=\ngonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=\ngoogle.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=\ngoogle.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=\ngoogle.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=\ngoogle.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=\ngoogle.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=\ngoogle.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=\ngoogle.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=\ngoogle.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=\ngoogle.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=\ngoogle.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=\ngoogle.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=\ngoogle.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=\ngoogle.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw=\ngoogle.golang.org/api v0.267.0 h1:w+vfWPMPYeRs8qH1aYYsFX68jMls5acWl/jocfLomwE=\ngoogle.golang.org/api v0.267.0/go.mod h1:Jzc0+ZfLnyvXma3UtaTl023TdhZu6OMBP9tJ+0EmFD0=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=\ngoogle.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=\ngoogle.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=\ngoogle.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM=\ngoogle.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20 h1:7ei4lp52gK1uSejlA8AZl5AJjeLUOHBQscRQZUgAcu0=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20/go.mod h1:ZdbssH/1SOVnjnDlXzxDHK2MCidiqXtbYccJNzNYPEE=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20 h1:Jr5R2J6F6qWyzINc+4AM8t5pfUz6beZpHp678GNrMbE=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260203192932-546029d2fa20/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=\ngoogle.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=\ngoogle.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=\ngoogle.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=\ngoogle.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=\ngoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngoogle.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=\ngopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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=\ngotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=\ngotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nmodernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=\nmodernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=\nmodernc.org/ccgo/v4 v4.30.1 h1:4r4U1J6Fhj98NKfSjnPUN7Ze2c6MnAdL0hWw6+LrJpc=\nmodernc.org/ccgo/v4 v4.30.1/go.mod h1:bIOeI1JL54Utlxn+LwrFyjCx2n2RDiYEaJVSrgdrRfM=\nmodernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA=\nmodernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=\nmodernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=\nmodernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=\nmodernc.org/gc/v3 v3.1.1 h1:k8T3gkXWY9sEiytKhcgyiZ2L0DTyCQ/nvX+LoCljoRE=\nmodernc.org/gc/v3 v3.1.1/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=\nmodernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=\nmodernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=\nmodernc.org/libc v1.67.6 h1:eVOQvpModVLKOdT+LvBPjdQqfrZq+pC39BygcT+E7OI=\nmodernc.org/libc v1.67.6/go.mod h1:JAhxUVlolfYDErnwiqaLvUqc8nfb2r6S6slAgZOnaiE=\nmodernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=\nmodernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=\nmodernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=\nmodernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=\nmodernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=\nmodernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=\nmodernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=\nmodernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=\nmodernc.org/sqlite v1.46.1 h1:eFJ2ShBLIEnUWlLy12raN0Z1plqmFX9Qe3rjQTKt6sU=\nmodernc.org/sqlite v1.46.1/go.mod h1:CzbrU2lSB1DKUusvwGz7rqEKIq+NUd8GWuBBZDs9/nA=\nmodernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=\nmodernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=\nmodernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=\nmodernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=\npgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=\npgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\n"
  },
  {
    "path": "tools.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n//go:build tools\n\npackage tools\n\nimport (\n\t// document generation\n\t_ \"github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs\"\n)\n"
  }
]