├── .copywrite.hcl ├── .github ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── FUNDING.yml ├── config │ ├── acceptance_tests_kind_config.yaml │ ├── acceptance_tests_kind_config2.yaml │ └── seccomp-profiles │ │ └── audit.json ├── dependabot.yml ├── tf │ ├── cilium │ │ ├── main.tf │ │ └── versions.tf │ ├── clustermesh │ │ ├── main.tf │ │ └── versions.tf │ ├── kubeproxy-free │ │ ├── main.tf │ │ └── versions.tf │ ├── provider-config-content │ │ ├── main.tf │ │ └── versions.tf │ └── versions.tf └── workflows │ ├── release.yml │ └── test.yml ├── .gitignore ├── .golangci.yml ├── .goreleaser.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── GNUmakefile ├── LICENSE ├── README.md ├── cilium ├── cluster_mesh_connect.go ├── cluster_mesh_enable.go ├── cluster_mesh_enable_test.go ├── config.go ├── config_test.go ├── data_helm_values.go ├── data_helm_values_test.go ├── helper.go ├── hubble.go ├── hubble_test.go ├── install.go ├── install_test.go ├── kubeproxy_free.go ├── kubeproxy_free_test.go ├── provider.go └── provider_test.go ├── docs ├── data-sources │ └── helm_values.md ├── index.md └── resources │ ├── cilium.md │ ├── clustermesh.md │ ├── clustermesh_connection.md │ ├── config.md │ ├── hubble.md │ └── kubeproxy_free.md ├── examples ├── README.md ├── data-sources │ └── helm_values │ │ └── example_1.tf ├── provider │ └── provider.tf └── resources │ ├── cilium │ └── example_1.tf │ ├── clustermesh │ └── example_1.tf │ ├── clustermesh_connection │ └── example_1.tf │ ├── config │ └── example_1.tf │ ├── hubble │ └── example_1.tf │ └── kubeproxy_free │ └── example_1.tf ├── go.mod ├── go.sum ├── main.go ├── renovate.json ├── templates ├── data-sources │ └── helm_values.md.tmpl ├── index.md.tmpl └── resources │ ├── cilium.md.tmpl │ ├── clustermesh.md.tmpl │ ├── clustermesh_connection.md.tmpl │ ├── config.md.tmpl │ ├── hubble.md.tmpl │ └── kubeproxy_free.md.tmpl ├── terraform-registry-manifest.json └── tools └── tools.go /.copywrite.hcl: -------------------------------------------------------------------------------- 1 | # NOTE: This file is for HashiCorp specific licensing automation and can be deleted after creating a new repo with this template. 2 | schema_version = 1 3 | 4 | project { 5 | license = "MPL-2.0" 6 | copyright_year = 2021 7 | 8 | header_ignore = [ 9 | # examples used within documentation (prose) 10 | "examples/**", 11 | 12 | # GitHub issue template configuration 13 | ".github/ISSUE_TEMPLATE/*.yml", 14 | 15 | # golangci-lint tooling configuration 16 | ".golangci.yml", 17 | 18 | # GoReleaser tooling configuration 19 | ".goreleaser.yml", 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @hashicorp/terraform-devex 2 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | HashiCorp Community Guidelines apply to you when interacting with the community here on GitHub and contributing code. 4 | 5 | Please read the full text at https://www.hashicorp.com/community-guidelines 6 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [littlejo] 4 | -------------------------------------------------------------------------------- /.github/config/acceptance_tests_kind_config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kind.x-k8s.io/v1alpha4 2 | kind: Cluster 3 | nodes: 4 | - role: control-plane 5 | image: kindest/node:v1.30.2 6 | extraMounts: 7 | - hostPath: "./.github/config/seccomp-profiles" 8 | containerPath: "/var/lib/kubelet/seccomp/profiles" 9 | networking: 10 | disableDefaultCNI: true 11 | podSubnet: "10.1.0.0/16" 12 | serviceSubnet: "172.20.1.0/24" 13 | -------------------------------------------------------------------------------- /.github/config/acceptance_tests_kind_config2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kind.x-k8s.io/v1alpha4 2 | kind: Cluster 3 | nodes: 4 | - role: control-plane 5 | image: kindest/node:v1.30.2 6 | extraMounts: 7 | - hostPath: "./.github/config/seccomp-profiles" 8 | containerPath: "/var/lib/kubelet/seccomp/profiles" 9 | networking: 10 | disableDefaultCNI: true 11 | podSubnet: "10.2.0.0/16" 12 | serviceSubnet: "172.20.2.0/24" 13 | -------------------------------------------------------------------------------- /.github/config/seccomp-profiles/audit.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultAction": "SCMP_ACT_LOG" 3 | } 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # See GitHub's documentation for more information on this file: 2 | # https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates 3 | version: 2 4 | updates: 5 | - package-ecosystem: "gomod" 6 | directory: "/" 7 | schedule: 8 | interval: "daily" 9 | -------------------------------------------------------------------------------- /.github/tf/cilium/main.tf: -------------------------------------------------------------------------------- 1 | provider "cilium" { 2 | namespace = "cilium" 3 | } 4 | 5 | provider "cilium" { 6 | alias = "preflight" 7 | namespace = "cilium" 8 | helm_release = "cilium-preflight" 9 | } 10 | 11 | resource "cilium" "this" { 12 | version = "1.16.0" 13 | set = [ 14 | "hubble.relay.enabled=true", 15 | "hubble.ui.enabled=true", 16 | ] 17 | } 18 | 19 | resource "cilium" "preflight" { 20 | version = "1.16.1" 21 | set = [ 22 | "preflight.enabled=true", 23 | "agent=false", 24 | "operator.enabled=false", 25 | ] 26 | provider = cilium.preflight 27 | } 28 | 29 | output "cilium_ca" { 30 | value = nonsensitive(cilium.this.ca) 31 | } 32 | -------------------------------------------------------------------------------- /.github/tf/cilium/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | cilium = { 4 | source = "littlejo/cilium" 5 | version = ">= 0.2.0" 6 | } 7 | } 8 | required_version = ">= 1.3" 9 | } 10 | -------------------------------------------------------------------------------- /.github/tf/clustermesh/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | cert = cilium.this.ca["crt"] 3 | key = cilium.this.ca["key"] 4 | } 5 | 6 | provider "cilium" { 7 | alias = "mesh1" 8 | context = "kind-test1" 9 | } 10 | 11 | provider "cilium" { 12 | alias = "mesh2" 13 | context = "kind-test2" 14 | } 15 | 16 | resource "cilium" "this" { 17 | set = [ 18 | "cluster.name=mesh1", 19 | "cluster.id=1", 20 | "ipam.mode=kubernetes", 21 | ] 22 | version = "1.16.1" 23 | provider = cilium.mesh1 24 | } 25 | 26 | output "cilium_ca1" { 27 | value = nonsensitive(cilium.this.ca) 28 | } 29 | 30 | resource "cilium_clustermesh" "this" { 31 | service_type = "NodePort" 32 | depends_on = [ 33 | cilium.this 34 | ] 35 | provider = cilium.mesh1 36 | } 37 | 38 | resource "cilium" "this2" { 39 | set = [ 40 | "cluster.name=mesh2", 41 | "cluster.id=2", 42 | "ipam.mode=kubernetes", 43 | "tls.ca.cert=${local.cert}", 44 | "tls.ca.key=${local.key}", 45 | ] 46 | version = "1.16.1" 47 | provider = cilium.mesh2 48 | } 49 | 50 | output "cilium_ca2" { 51 | value = nonsensitive(cilium.this2.ca) 52 | } 53 | 54 | resource "cilium_clustermesh" "this2" { 55 | service_type = "NodePort" 56 | depends_on = [ 57 | cilium.this2 58 | ] 59 | provider = cilium.mesh2 60 | } 61 | 62 | resource "cilium_clustermesh_connection" "this" { 63 | destination_contexts = ["kind-test2"] 64 | provider = cilium.mesh1 65 | depends_on = [ 66 | cilium_clustermesh.this, 67 | cilium_clustermesh.this2, 68 | ] 69 | } 70 | -------------------------------------------------------------------------------- /.github/tf/clustermesh/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | cilium = { 4 | source = "littlejo/cilium" 5 | version = ">= 0.2.0" 6 | } 7 | } 8 | required_version = ">= 1.3" 9 | } 10 | -------------------------------------------------------------------------------- /.github/tf/kubeproxy-free/main.tf: -------------------------------------------------------------------------------- 1 | provider "cilium" { 2 | } 3 | 4 | resource "cilium_kubeproxy_free" "this" { 5 | } 6 | -------------------------------------------------------------------------------- /.github/tf/kubeproxy-free/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | cilium = { 4 | source = "littlejo/cilium" 5 | version = ">= 0.2.0" 6 | } 7 | } 8 | required_version = ">= 1.3" 9 | } 10 | -------------------------------------------------------------------------------- /.github/tf/provider-config-content/main.tf: -------------------------------------------------------------------------------- 1 | variable "config_content" { 2 | } 3 | 4 | provider "cilium" { 5 | config_content = var.config_content 6 | } 7 | 8 | resource "cilium" "this" { 9 | version = "1.16.1" 10 | } 11 | -------------------------------------------------------------------------------- /.github/tf/provider-config-content/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | cilium = { 4 | source = "littlejo/cilium" 5 | version = ">= 0.2.0" 6 | } 7 | } 8 | required_version = ">= 1.3" 9 | } 10 | -------------------------------------------------------------------------------- /.github/tf/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | cilium = { 4 | source = "terraform.local/local/cilium" 5 | version = "0.0.1" 6 | } 7 | } 8 | required_version = ">= 1.3" 9 | } 10 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # Terraform Provider release workflow. 2 | name: Release 3 | 4 | # This GitHub action creates a release when a tag that matches the pattern 5 | # "v*" (e.g. v0.1.0) is created. 6 | on: 7 | push: 8 | tags: 9 | - 'v*' 10 | 11 | # Releases need permissions to read and write the repository contents. 12 | # GitHub considers creating releases and uploading assets as writing contents. 13 | permissions: 14 | contents: write 15 | 16 | jobs: 17 | goreleaser: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 21 | with: 22 | # Allow goreleaser to access older tag information. 23 | fetch-depth: 0 24 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 25 | with: 26 | go-version-file: 'go.mod' 27 | cache: true 28 | - name: Import GPG key 29 | uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0 30 | id: import_gpg 31 | with: 32 | gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} 33 | passphrase: ${{ secrets.PASSPHRASE }} 34 | - name: Run GoReleaser 35 | uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 36 | with: 37 | args: release --clean 38 | env: 39 | # GitHub sets the GITHUB_TOKEN secret automatically. 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} 42 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | # Terraform Provider testing workflow. 2 | name: Tests 3 | 4 | # This GitHub action runs your tests for each pull request and push. 5 | # Optionally, you can turn it on using a schedule for regular testing. 6 | on: 7 | pull_request: 8 | paths-ignore: 9 | - 'README.md' 10 | push: 11 | paths-ignore: 12 | - 'README.md' 13 | 14 | # Testing only needs permissions to read the repository contents. 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | # Ensure project builds before running testing matrix 20 | build: 21 | name: Build 22 | runs-on: ubuntu-latest 23 | timeout-minutes: 10 24 | steps: 25 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 26 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 27 | with: 28 | go-version-file: 'go.mod' 29 | cache: true 30 | - run: go mod download 31 | - run: go build -v . 32 | - name: Run linters 33 | uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0 34 | with: 35 | version: latest 36 | 37 | generate: 38 | runs-on: ubuntu-latest 39 | steps: 40 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 41 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 42 | with: 43 | go-version-file: 'go.mod' 44 | cache: true 45 | - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 46 | with: 47 | terraform_wrapper: false 48 | - run: go generate ./... 49 | - name: git diff 50 | run: | 51 | git diff --compact-summary --exit-code || \ 52 | (echo; echo "Unexpected difference in directories after code generation. Run 'go generate ./...' command and commit."; exit 1) 53 | 54 | goreleaser: 55 | runs-on: ubuntu-latest 56 | steps: 57 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 58 | with: 59 | # Allow goreleaser to access older tag information. 60 | fetch-depth: 0 61 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 62 | with: 63 | go-version-file: 'go.mod' 64 | cache: true 65 | - name: Run GoReleaser 66 | uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 67 | with: 68 | args: check 69 | env: 70 | # GitHub sets the GITHUB_TOKEN secret automatically. 71 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 72 | GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} 73 | 74 | # Run acceptance tests in a matrix with Terraform CLI versions 75 | test-tofu: 76 | name: Opentofu Provider Acceptance Tests 77 | needs: build 78 | runs-on: ubuntu-latest 79 | timeout-minutes: 15 80 | strategy: 81 | fail-fast: false 82 | matrix: 83 | # list whatever tofu versions here you would like to support 84 | tofu: 85 | - '1.7.*' 86 | - '1.8.*' 87 | steps: 88 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 89 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 90 | with: 91 | go-version-file: 'go.mod' 92 | cache: true 93 | - uses: opentofu/setup-opentofu@v1 94 | with: 95 | tofu_version: ${{ matrix.tofu }} 96 | tofu_wrapper: false 97 | - name: Setup kind 98 | uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 99 | with: 100 | wait: 0 101 | config: .github/config/acceptance_tests_kind_config.yaml 102 | - run: go mod download 103 | - env: 104 | TF_ACC: "1" 105 | TF_ACC_PROVIDER_NAMESPACE: "hashicorp" 106 | TF_ACC_PROVIDER_HOST: "registry.opentofu.org" 107 | run: TF_ACC_TERRAFORM_PATH=$(which tofu) go test -v -cover ./cilium 108 | timeout-minutes: 10 109 | 110 | test: 111 | name: Terraform Provider Acceptance Tests 112 | needs: build 113 | runs-on: ubuntu-latest 114 | timeout-minutes: 15 115 | strategy: 116 | fail-fast: false 117 | matrix: 118 | # list whatever Terraform versions here you would like to support 119 | terraform: 120 | - '1.5.*' 121 | - '1.6.*' 122 | - '1.7.*' 123 | - '1.8.*' 124 | - '1.10.0-alpha20240828' 125 | steps: 126 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 127 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 128 | with: 129 | go-version-file: 'go.mod' 130 | cache: true 131 | - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 132 | with: 133 | terraform_version: ${{ matrix.terraform }} 134 | terraform_wrapper: false 135 | - name: Setup kind 136 | uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 137 | with: 138 | wait: 0 139 | config: .github/config/acceptance_tests_kind_config.yaml 140 | - run: go mod download 141 | - env: 142 | TF_ACC: "1" 143 | run: go test -v -cover ./cilium 144 | timeout-minutes: 10 145 | 146 | test-cluster-mesh: 147 | name: "Functionnal test: Clustermesh" 148 | runs-on: ubuntu-latest 149 | timeout-minutes: 15 150 | strategy: 151 | fail-fast: false 152 | matrix: 153 | # list whatever tofu versions here you would like to support 154 | tofu: 155 | - '1.8.*' 156 | steps: 157 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 158 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 159 | with: 160 | go-version-file: 'go.mod' 161 | cache: true 162 | - uses: opentofu/setup-opentofu@v1 163 | with: 164 | tofu_version: ${{ matrix.tofu }} 165 | tofu_wrapper: true 166 | - name: Setup kind test1 167 | uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 168 | with: 169 | wait: 0 170 | config: .github/config/acceptance_tests_kind_config.yaml 171 | cluster_name: "test1" 172 | - name: Setup kind test2 173 | uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 174 | with: 175 | wait: 0 176 | config: .github/config/acceptance_tests_kind_config2.yaml 177 | cluster_name: "test2" 178 | - run: make 179 | - run: cp .github/tf/versions.tf .github/tf/clustermesh 180 | - run: tofu init 181 | working-directory: .github/tf/clustermesh 182 | - run: tofu apply -auto-approve 183 | working-directory: .github/tf/clustermesh 184 | - run: tofu destroy -auto-approve 185 | working-directory: .github/tf/clustermesh 186 | 187 | test-kubeproxy-free: 188 | name: "Functionnal test: kubeproxy-free" 189 | runs-on: ubuntu-latest 190 | timeout-minutes: 15 191 | strategy: 192 | fail-fast: false 193 | matrix: 194 | # list whatever tofu versions here you would like to support 195 | tofu: 196 | - '1.8.*' 197 | steps: 198 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 199 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 200 | with: 201 | go-version-file: 'go.mod' 202 | cache: true 203 | - uses: opentofu/setup-opentofu@v1 204 | with: 205 | tofu_version: ${{ matrix.tofu }} 206 | tofu_wrapper: true 207 | - name: Setup kind test1 208 | uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 209 | with: 210 | wait: 0 211 | config: .github/config/acceptance_tests_kind_config.yaml 212 | cluster_name: "test1" 213 | - run: make 214 | - run: cp .github/tf/versions.tf .github/tf/kubeproxy-free 215 | - run: tofu init 216 | working-directory: .github/tf/kubeproxy-free 217 | - run: tofu apply -auto-approve 218 | working-directory: .github/tf/kubeproxy-free 219 | - run: kubectl get ds/kube-proxy -n kube-system -o jsonpath='{.status.currentNumberScheduled}' | grep -q 0 220 | - run: tofu destroy -auto-approve 221 | working-directory: .github/tf/kubeproxy-free 222 | 223 | test-cilium-install: 224 | name: "Functionnal test: cilium-install" 225 | runs-on: ubuntu-latest 226 | timeout-minutes: 15 227 | strategy: 228 | fail-fast: false 229 | matrix: 230 | # list whatever tofu versions here you would like to support 231 | tofu: 232 | - '1.8.*' 233 | steps: 234 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 235 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 236 | with: 237 | go-version-file: 'go.mod' 238 | cache: true 239 | - uses: opentofu/setup-opentofu@v1 240 | with: 241 | tofu_version: ${{ matrix.tofu }} 242 | tofu_wrapper: true 243 | - name: Setup kind test1 244 | uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 245 | with: 246 | wait: 0 247 | config: .github/config/acceptance_tests_kind_config.yaml 248 | cluster_name: "test1" 249 | - run: make 250 | - run: cp .github/tf/versions.tf .github/tf/cilium/ 251 | - run: kubectl create namespace cilium 252 | - run: tofu init 253 | working-directory: .github/tf/cilium 254 | - run: tofu apply -auto-approve 255 | working-directory: .github/tf/cilium 256 | - run: kubectl get pod -n cilium 257 | - run: tofu destroy -auto-approve 258 | working-directory: .github/tf/cilium 259 | - run: kubectl get pod -n cilium 260 | 261 | test-content-provider: 262 | name: "Functionnal test: attribute config_content" 263 | runs-on: ubuntu-latest 264 | env: 265 | dir: .github/tf/provider-config-content/ 266 | timeout-minutes: 15 267 | strategy: 268 | fail-fast: false 269 | matrix: 270 | # list whatever tofu versions here you would like to support 271 | tofu: 272 | - '1.8.*' 273 | steps: 274 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 275 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 276 | with: 277 | go-version-file: 'go.mod' 278 | cache: true 279 | - uses: opentofu/setup-opentofu@v1 280 | with: 281 | tofu_version: ${{ matrix.tofu }} 282 | tofu_wrapper: true 283 | - name: Setup kind test1 284 | uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 285 | with: 286 | wait: 0 287 | config: .github/config/acceptance_tests_kind_config.yaml 288 | cluster_name: "test1" 289 | - run: make 290 | - run: cp .github/tf/versions.tf $dir 291 | - run: echo "config_content = \"$(cat ${HOME}/.kube/config | base64 -w 0)\"" > $dir/tofu.auto.tfvars 292 | - run: cat $dir/tofu.auto.tfvars 293 | - run: tofu init 294 | working-directory: ${{ env.dir }} 295 | - run: tofu plan 296 | working-directory: ${{ env.dir }} 297 | - run: ls 2>/dev/null -l /tmp/kubeconfig* | wc -l 298 | - run: tofu apply -auto-approve 299 | working-directory: ${{ env.dir }} 300 | - run: ls 2>/dev/null -l /tmp/kubeconfig* | wc -l 301 | - run: tofu destroy -auto-approve 302 | working-directory: ${{ env.dir }} 303 | - run: ls 2>/dev/null -l /tmp/kubeconfig* | wc -l 304 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.dll 2 | *.exe 3 | .DS_Store 4 | example.tf 5 | terraform.tfplan 6 | terraform.tfstate 7 | bin/ 8 | dist/ 9 | modules-dev/ 10 | /pkg/ 11 | website/.vagrant 12 | website/.bundle 13 | website/build 14 | website/node_modules 15 | .vagrant/ 16 | *.backup 17 | ./*.tfstate 18 | .terraform/ 19 | *.log 20 | *.bak 21 | *~ 22 | .*.swp 23 | .idea 24 | *.iml 25 | *.test 26 | *.iml 27 | 28 | website/vendor 29 | 30 | # Test exclusions 31 | !command/test-fixtures/**/*.tfstate 32 | !command/test-fixtures/**/.terraform/ 33 | 34 | # Keep windows files with windows line endings 35 | *.winfile eol=crlf 36 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | linters: 3 | default: none 4 | enable: 5 | - copyloopvar 6 | - durationcheck 7 | - errcheck 8 | - forcetypeassert 9 | - godot 10 | - ineffassign 11 | - makezero 12 | - misspell 13 | - nilerr 14 | - predeclared 15 | - staticcheck 16 | - unconvert 17 | - unparam 18 | - unused 19 | - usetesting 20 | exclusions: 21 | generated: lax 22 | presets: 23 | - comments 24 | - common-false-positives 25 | - legacy 26 | - std-error-handling 27 | paths: 28 | - third_party$ 29 | - builtin$ 30 | - examples$ 31 | issues: 32 | max-issues-per-linter: 0 33 | max-same-issues: 0 34 | formatters: 35 | enable: 36 | - gofmt 37 | exclusions: 38 | generated: lax 39 | paths: 40 | - third_party$ 41 | - builtin$ 42 | - examples$ 43 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | # Visit https://goreleaser.com for documentation on how to customize this 4 | # behavior. 5 | before: 6 | hooks: 7 | # this is just an example and not a requirement for provider building/publishing 8 | - go mod tidy 9 | builds: 10 | - env: 11 | # goreleaser does not work with CGO, it could also complicate 12 | # usage by users in CI/CD systems like Terraform Cloud where 13 | # they are unable to install libraries. 14 | - CGO_ENABLED=0 15 | mod_timestamp: '{{ .CommitTimestamp }}' 16 | flags: 17 | - -trimpath 18 | ldflags: 19 | - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}' 20 | goos: 21 | - freebsd 22 | - windows 23 | - linux 24 | - darwin 25 | goarch: 26 | - amd64 27 | - '386' 28 | - arm 29 | - arm64 30 | ignore: 31 | - goos: darwin 32 | goarch: '386' 33 | - goos: freebsd 34 | 35 | binary: '{{ .ProjectName }}_v{{ .Version }}' 36 | archives: 37 | - formats: [ 'zip' ] 38 | name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' 39 | checksum: 40 | extra_files: 41 | - glob: 'terraform-registry-manifest.json' 42 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' 43 | name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' 44 | algorithm: sha256 45 | signs: 46 | - artifacts: checksum 47 | args: 48 | # if you are using this in a GitHub action or some other automated pipeline, you 49 | # need to pass the batch flag to indicate its not interactive. 50 | - "--batch" 51 | - "--local-user" 52 | - "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key 53 | - "--output" 54 | - "${signature}" 55 | - "--detach-sign" 56 | - "${artifact}" 57 | release: 58 | extra_files: 59 | - glob: 'terraform-registry-manifest.json' 60 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' 61 | # If you want to manually examine the release before its live, uncomment this line: 62 | # draft: true 63 | changelog: 64 | disable: true 65 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.0 (Unreleased) 2 | 3 | FEATURES: 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Thanks for wanting to contribute to this project ❤️. 2 | 3 | This project accepts contributions. In order to contribute, you should pay attention to a few things: 4 | 5 | 1. Your code must follow the coding style rules 6 | 2. Your code must be fully documented 7 | 3. Your code must have acceptance test 8 | 4. Your new resource needs to be imported by the user 9 | 5. Please test your new resources, datasources and acceptance tests 10 | 6. GitHub Pull Requests 11 | 12 | ## Coding and documentation Style: 13 | 14 | - Code must be formatted with `make fmt` command 15 | - Documentation must be created with `make doc` command 16 | 17 | ## Acceptance tests: 18 | 19 | - Each resource and/or datasource need to have an acceptance test 20 | - Acceptance tests must be run and must pass 21 | - Don't forget to add or modify existing sweeper method if you think the acceptance tests may leave orphan resources on failure 22 | 23 | ## Submitting Modifications: 24 | 25 | The contributions should be submitted through new GitHub Pull Requests. 26 | -------------------------------------------------------------------------------- /GNUmakefile: -------------------------------------------------------------------------------- 1 | TEST?=$$(go list ./... | grep -v 'vendor') 2 | GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor) 3 | HOSTNAME=terraform.local 4 | # HOSTNAME=registry.terraform.io 5 | NAMESPACE=local 6 | # NAMESPACE=hashicorp 7 | NAME=cilium 8 | BINARY=terraform-provider-${NAME} 9 | VERSION=0.0.1 10 | OS_ARCH=linux_amd64 11 | 12 | default: install 13 | 14 | build: 15 | go build -o ${BINARY} 16 | 17 | build-linux: 18 | env GOOS=linux GOARCH=amd64 go build -o ${BINARY} 19 | 20 | fmt: 21 | gofmt -w $(GOFMT_FILES) 22 | 23 | doc: 24 | go generate 25 | 26 | release: 27 | goreleaser release --clean --snapshot --skip-publish --skip-sign 28 | 29 | install: build 30 | mkdir -p ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH} 31 | mv ${BINARY} ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH} 32 | 33 | test: 34 | go test -i $(TEST) || exit 1 35 | echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 36 | 37 | # Run acceptance tests 38 | .PHONY: testacc 39 | testacc: 40 | TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 HashiCorp, Inc. 2 | 3 | Mozilla Public License Version 2.0 4 | ================================== 5 | 6 | 1. Definitions 7 | -------------- 8 | 9 | 1.1. "Contributor" 10 | means each individual or legal entity that creates, contributes to 11 | the creation of, or owns Covered Software. 12 | 13 | 1.2. "Contributor Version" 14 | means the combination of the Contributions of others (if any) used 15 | by a Contributor and that particular Contributor's Contribution. 16 | 17 | 1.3. "Contribution" 18 | means Covered Software of a particular Contributor. 19 | 20 | 1.4. "Covered Software" 21 | means Source Code Form to which the initial Contributor has attached 22 | the notice in Exhibit A, the Executable Form of such Source Code 23 | Form, and Modifications of such Source Code Form, in each case 24 | including portions thereof. 25 | 26 | 1.5. "Incompatible With Secondary Licenses" 27 | means 28 | 29 | (a) that the initial Contributor has attached the notice described 30 | in Exhibit B to the Covered Software; or 31 | 32 | (b) that the Covered Software was made available under the terms of 33 | version 1.1 or earlier of the License, but not also under the 34 | terms of a Secondary License. 35 | 36 | 1.6. "Executable Form" 37 | means any form of the work other than Source Code Form. 38 | 39 | 1.7. "Larger Work" 40 | means a work that combines Covered Software with other material, in 41 | a separate file or files, that is not Covered Software. 42 | 43 | 1.8. "License" 44 | means this document. 45 | 46 | 1.9. "Licensable" 47 | means having the right to grant, to the maximum extent possible, 48 | whether at the time of the initial grant or subsequently, any and 49 | all of the rights conveyed by this License. 50 | 51 | 1.10. "Modifications" 52 | means any of the following: 53 | 54 | (a) any file in Source Code Form that results from an addition to, 55 | deletion from, or modification of the contents of Covered 56 | Software; or 57 | 58 | (b) any new file in Source Code Form that contains any Covered 59 | Software. 60 | 61 | 1.11. "Patent Claims" of a Contributor 62 | means any patent claim(s), including without limitation, method, 63 | process, and apparatus claims, in any patent Licensable by such 64 | Contributor that would be infringed, but for the grant of the 65 | License, by the making, using, selling, offering for sale, having 66 | made, import, or transfer of either its Contributions or its 67 | Contributor Version. 68 | 69 | 1.12. "Secondary License" 70 | means either the GNU General Public License, Version 2.0, the GNU 71 | Lesser General Public License, Version 2.1, the GNU Affero General 72 | Public License, Version 3.0, or any later versions of those 73 | licenses. 74 | 75 | 1.13. "Source Code Form" 76 | means the form of the work preferred for making modifications. 77 | 78 | 1.14. "You" (or "Your") 79 | means an individual or a legal entity exercising rights under this 80 | License. For legal entities, "You" includes any entity that 81 | controls, is controlled by, or is under common control with You. For 82 | purposes of this definition, "control" means (a) the power, direct 83 | or indirect, to cause the direction or management of such entity, 84 | whether by contract or otherwise, or (b) ownership of more than 85 | fifty percent (50%) of the outstanding shares or beneficial 86 | ownership of such entity. 87 | 88 | 2. License Grants and Conditions 89 | -------------------------------- 90 | 91 | 2.1. Grants 92 | 93 | Each Contributor hereby grants You a world-wide, royalty-free, 94 | non-exclusive license: 95 | 96 | (a) under intellectual property rights (other than patent or trademark) 97 | Licensable by such Contributor to use, reproduce, make available, 98 | modify, display, perform, distribute, and otherwise exploit its 99 | Contributions, either on an unmodified basis, with Modifications, or 100 | as part of a Larger Work; and 101 | 102 | (b) under Patent Claims of such Contributor to make, use, sell, offer 103 | for sale, have made, import, and otherwise transfer either its 104 | Contributions or its Contributor Version. 105 | 106 | 2.2. Effective Date 107 | 108 | The licenses granted in Section 2.1 with respect to any Contribution 109 | become effective for each Contribution on the date the Contributor first 110 | distributes such Contribution. 111 | 112 | 2.3. Limitations on Grant Scope 113 | 114 | The licenses granted in this Section 2 are the only rights granted under 115 | this License. No additional rights or licenses will be implied from the 116 | distribution or licensing of Covered Software under this License. 117 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 118 | Contributor: 119 | 120 | (a) for any code that a Contributor has removed from Covered Software; 121 | or 122 | 123 | (b) for infringements caused by: (i) Your and any other third party's 124 | modifications of Covered Software, or (ii) the combination of its 125 | Contributions with other software (except as part of its Contributor 126 | Version); or 127 | 128 | (c) under Patent Claims infringed by Covered Software in the absence of 129 | its Contributions. 130 | 131 | This License does not grant any rights in the trademarks, service marks, 132 | or logos of any Contributor (except as may be necessary to comply with 133 | the notice requirements in Section 3.4). 134 | 135 | 2.4. Subsequent Licenses 136 | 137 | No Contributor makes additional grants as a result of Your choice to 138 | distribute the Covered Software under a subsequent version of this 139 | License (see Section 10.2) or under the terms of a Secondary License (if 140 | permitted under the terms of Section 3.3). 141 | 142 | 2.5. Representation 143 | 144 | Each Contributor represents that the Contributor believes its 145 | Contributions are its original creation(s) or it has sufficient rights 146 | to grant the rights to its Contributions conveyed by this License. 147 | 148 | 2.6. Fair Use 149 | 150 | This License is not intended to limit any rights You have under 151 | applicable copyright doctrines of fair use, fair dealing, or other 152 | equivalents. 153 | 154 | 2.7. Conditions 155 | 156 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 157 | in Section 2.1. 158 | 159 | 3. Responsibilities 160 | ------------------- 161 | 162 | 3.1. Distribution of Source Form 163 | 164 | All distribution of Covered Software in Source Code Form, including any 165 | Modifications that You create or to which You contribute, must be under 166 | the terms of this License. You must inform recipients that the Source 167 | Code Form of the Covered Software is governed by the terms of this 168 | License, and how they can obtain a copy of this License. You may not 169 | attempt to alter or restrict the recipients' rights in the Source Code 170 | Form. 171 | 172 | 3.2. Distribution of Executable Form 173 | 174 | If You distribute Covered Software in Executable Form then: 175 | 176 | (a) such Covered Software must also be made available in Source Code 177 | Form, as described in Section 3.1, and You must inform recipients of 178 | the Executable Form how they can obtain a copy of such Source Code 179 | Form by reasonable means in a timely manner, at a charge no more 180 | than the cost of distribution to the recipient; and 181 | 182 | (b) You may distribute such Executable Form under the terms of this 183 | License, or sublicense it under different terms, provided that the 184 | license for the Executable Form does not attempt to limit or alter 185 | the recipients' rights in the Source Code Form under this License. 186 | 187 | 3.3. Distribution of a Larger Work 188 | 189 | You may create and distribute a Larger Work under terms of Your choice, 190 | provided that You also comply with the requirements of this License for 191 | the Covered Software. If the Larger Work is a combination of Covered 192 | Software with a work governed by one or more Secondary Licenses, and the 193 | Covered Software is not Incompatible With Secondary Licenses, this 194 | License permits You to additionally distribute such Covered Software 195 | under the terms of such Secondary License(s), so that the recipient of 196 | the Larger Work may, at their option, further distribute the Covered 197 | Software under the terms of either this License or such Secondary 198 | License(s). 199 | 200 | 3.4. Notices 201 | 202 | You may not remove or alter the substance of any license notices 203 | (including copyright notices, patent notices, disclaimers of warranty, 204 | or limitations of liability) contained within the Source Code Form of 205 | the Covered Software, except that You may alter any license notices to 206 | the extent required to remedy known factual inaccuracies. 207 | 208 | 3.5. Application of Additional Terms 209 | 210 | You may choose to offer, and to charge a fee for, warranty, support, 211 | indemnity or liability obligations to one or more recipients of Covered 212 | Software. However, You may do so only on Your own behalf, and not on 213 | behalf of any Contributor. You must make it absolutely clear that any 214 | such warranty, support, indemnity, or liability obligation is offered by 215 | You alone, and You hereby agree to indemnify every Contributor for any 216 | liability incurred by such Contributor as a result of warranty, support, 217 | indemnity or liability terms You offer. You may include additional 218 | disclaimers of warranty and limitations of liability specific to any 219 | jurisdiction. 220 | 221 | 4. Inability to Comply Due to Statute or Regulation 222 | --------------------------------------------------- 223 | 224 | If it is impossible for You to comply with any of the terms of this 225 | License with respect to some or all of the Covered Software due to 226 | statute, judicial order, or regulation then You must: (a) comply with 227 | the terms of this License to the maximum extent possible; and (b) 228 | describe the limitations and the code they affect. Such description must 229 | be placed in a text file included with all distributions of the Covered 230 | Software under this License. Except to the extent prohibited by statute 231 | or regulation, such description must be sufficiently detailed for a 232 | recipient of ordinary skill to be able to understand it. 233 | 234 | 5. Termination 235 | -------------- 236 | 237 | 5.1. The rights granted under this License will terminate automatically 238 | if You fail to comply with any of its terms. However, if You become 239 | compliant, then the rights granted under this License from a particular 240 | Contributor are reinstated (a) provisionally, unless and until such 241 | Contributor explicitly and finally terminates Your grants, and (b) on an 242 | ongoing basis, if such Contributor fails to notify You of the 243 | non-compliance by some reasonable means prior to 60 days after You have 244 | come back into compliance. Moreover, Your grants from a particular 245 | Contributor are reinstated on an ongoing basis if such Contributor 246 | notifies You of the non-compliance by some reasonable means, this is the 247 | first time You have received notice of non-compliance with this License 248 | from such Contributor, and You become compliant prior to 30 days after 249 | Your receipt of the notice. 250 | 251 | 5.2. If You initiate litigation against any entity by asserting a patent 252 | infringement claim (excluding declaratory judgment actions, 253 | counter-claims, and cross-claims) alleging that a Contributor Version 254 | directly or indirectly infringes any patent, then the rights granted to 255 | You by any and all Contributors for the Covered Software under Section 256 | 2.1 of this License shall terminate. 257 | 258 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 259 | end user license agreements (excluding distributors and resellers) which 260 | have been validly granted by You or Your distributors under this License 261 | prior to termination shall survive termination. 262 | 263 | ************************************************************************ 264 | * * 265 | * 6. Disclaimer of Warranty * 266 | * ------------------------- * 267 | * * 268 | * Covered Software is provided under this License on an "as is" * 269 | * basis, without warranty of any kind, either expressed, implied, or * 270 | * statutory, including, without limitation, warranties that the * 271 | * Covered Software is free of defects, merchantable, fit for a * 272 | * particular purpose or non-infringing. The entire risk as to the * 273 | * quality and performance of the Covered Software is with You. * 274 | * Should any Covered Software prove defective in any respect, You * 275 | * (not any Contributor) assume the cost of any necessary servicing, * 276 | * repair, or correction. This disclaimer of warranty constitutes an * 277 | * essential part of this License. No use of any Covered Software is * 278 | * authorized under this License except under this disclaimer. * 279 | * * 280 | ************************************************************************ 281 | 282 | ************************************************************************ 283 | * * 284 | * 7. Limitation of Liability * 285 | * -------------------------- * 286 | * * 287 | * Under no circumstances and under no legal theory, whether tort * 288 | * (including negligence), contract, or otherwise, shall any * 289 | * Contributor, or anyone who distributes Covered Software as * 290 | * permitted above, be liable to You for any direct, indirect, * 291 | * special, incidental, or consequential damages of any character * 292 | * including, without limitation, damages for lost profits, loss of * 293 | * goodwill, work stoppage, computer failure or malfunction, or any * 294 | * and all other commercial damages or losses, even if such party * 295 | * shall have been informed of the possibility of such damages. This * 296 | * limitation of liability shall not apply to liability for death or * 297 | * personal injury resulting from such party's negligence to the * 298 | * extent applicable law prohibits such limitation. Some * 299 | * jurisdictions do not allow the exclusion or limitation of * 300 | * incidental or consequential damages, so this exclusion and * 301 | * limitation may not apply to You. * 302 | * * 303 | ************************************************************************ 304 | 305 | 8. Litigation 306 | ------------- 307 | 308 | Any litigation relating to this License may be brought only in the 309 | courts of a jurisdiction where the defendant maintains its principal 310 | place of business and such litigation shall be governed by laws of that 311 | jurisdiction, without reference to its conflict-of-law provisions. 312 | Nothing in this Section shall prevent a party's ability to bring 313 | cross-claims or counter-claims. 314 | 315 | 9. Miscellaneous 316 | ---------------- 317 | 318 | This License represents the complete agreement concerning the subject 319 | matter hereof. If any provision of this License is held to be 320 | unenforceable, such provision shall be reformed only to the extent 321 | necessary to make it enforceable. Any law or regulation which provides 322 | that the language of a contract shall be construed against the drafter 323 | shall not be used to construe this License against a Contributor. 324 | 325 | 10. Versions of the License 326 | --------------------------- 327 | 328 | 10.1. New Versions 329 | 330 | Mozilla Foundation is the license steward. Except as provided in Section 331 | 10.3, no one other than the license steward has the right to modify or 332 | publish new versions of this License. Each version will be given a 333 | distinguishing version number. 334 | 335 | 10.2. Effect of New Versions 336 | 337 | You may distribute the Covered Software under the terms of the version 338 | of the License under which You originally received the Covered Software, 339 | or under the terms of any subsequent version published by the license 340 | steward. 341 | 342 | 10.3. Modified Versions 343 | 344 | If you create software not governed by this License, and you want to 345 | create a new license for such software, you may create and use a 346 | modified version of this License if you rename the license and remove 347 | any references to the name of the license steward (except to note that 348 | such modified license differs from this License). 349 | 350 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 351 | Licenses 352 | 353 | If You choose to distribute Source Code Form that is Incompatible With 354 | Secondary Licenses under the terms of this version of the License, the 355 | notice described in Exhibit B of this License must be attached. 356 | 357 | Exhibit A - Source Code Form License Notice 358 | ------------------------------------------- 359 | 360 | This Source Code Form is subject to the terms of the Mozilla Public 361 | License, v. 2.0. If a copy of the MPL was not distributed with this 362 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 363 | 364 | If it is not possible or desirable to put the notice in a particular 365 | file, then You may include the notice in a location (such as a LICENSE 366 | file in a relevant directory) where a recipient would be likely to look 367 | for such a notice. 368 | 369 | You may add additional accurate notices of copyright ownership. 370 | 371 | Exhibit B - "Incompatible With Secondary Licenses" Notice 372 | --------------------------------------------------------- 373 | 374 | This Source Code Form is "Incompatible With Secondary Licenses", as 375 | defined by the Mozilla Public License, v. 2.0. 376 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Terraform Cilium Provider (Experimental) 2 | ================== 3 | 4 | The Cilium Provider allows Terraform to manage [Cilium](https://cilium.io/) resources. 5 | 6 | - Website: [registry.terraform.io](https://registry.terraform.io/providers/littlejo/cilium/latest/docs) 7 | 8 | Requirements 9 | ------------ 10 | 11 | - [Terraform](https://www.terraform.io/downloads.html) > 1.5 or [OpenTofu](https://opentofu.org/docs/intro/install/) > 1.6 12 | - [Go](https://golang.org/doc/install) 1.22 (to build the provider plugin) 13 | 14 | Building The Provider 15 | --------------------- 16 | 17 | ```sh 18 | $ git clone https://github.com/littlejo/terraform-provider-cilium.git 19 | $ cd terraform-provider-cilium 20 | ``` 21 | 22 | Enter the provider directory and build the provider 23 | 24 | ```sh 25 | $ make build 26 | ``` 27 | 28 | Using the provider 29 | ---------------------- 30 | 31 | Please see the documentation in the [Terraform registry](https://registry.terraform.io/providers/littlejo/cilium/latest/docs). 32 | 33 | Or you can browse the documentation within this repo [here](https://github.com/littlejo/terraform-provider-cilium/tree/main/docs). 34 | 35 | Using the locally built provider 36 | ---------------------- 37 | 38 | If you wish to test the provider from the local version you just built, you can try the following method. 39 | 40 | First install the Terraform Provider binary into your local plugin repository: 41 | 42 | ```sh 43 | # Set your target environment (OS_architecture): linux_amd64, darwin_amd64... 44 | $ vim GNUmakefile 45 | $ make install 46 | ``` 47 | 48 | Then create a Terraform configuration using this exact provider: 49 | 50 | ```sh 51 | $ mkdir ~/test-terraform-provider-cilium 52 | $ cd ~/test-terraform-provider-cilium 53 | $ cat > main.tf < 105 | There is no small contribution, don't hesitate! 106 | 107 | Our awesome contributors: 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /cilium/cluster_mesh_connect.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "os" 10 | "strings" 11 | "time" 12 | 13 | "github.com/cilium/cilium/cilium-cli/clustermesh" 14 | 15 | "github.com/hashicorp/terraform-plugin-framework/path" 16 | "github.com/hashicorp/terraform-plugin-framework/resource" 17 | "github.com/hashicorp/terraform-plugin-framework/resource/schema" 18 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/int32default" 19 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/listdefault" 20 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" 21 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" 22 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" 23 | "github.com/hashicorp/terraform-plugin-framework/types" 24 | "github.com/hashicorp/terraform-plugin-log/tflog" 25 | ) 26 | 27 | // Ensure provider defined types fully satisfy framework interfaces. 28 | var _ resource.Resource = &CiliumClusterMeshConnectResource{} 29 | var _ resource.ResourceWithImportState = &CiliumClusterMeshConnectResource{} 30 | 31 | func NewCiliumClusterMeshConnectResource() resource.Resource { 32 | return &CiliumClusterMeshConnectResource{} 33 | } 34 | 35 | // CiliumClusterMeshConnectResource defines the resource implementation. 36 | type CiliumClusterMeshConnectResource struct { 37 | client *CiliumClient 38 | } 39 | 40 | // CiliumClusterMeshConnectResourceModel describes the resource data model. 41 | type CiliumClusterMeshConnectResourceModel struct { 42 | //SourceEndpoints types.List `tfsdk:"source_endpoint"` 43 | //DestinationEndpoints types.List `tfsdk:"destination_endpoint"` 44 | DestinationContexts types.List `tfsdk:"destination_contexts"` 45 | Parallel types.Int32 `tfsdk:"parallel"` 46 | ConnectionMode types.String `tfsdk:"connection_mode"` 47 | Id types.String `tfsdk:"id"` 48 | } 49 | 50 | func (r *CiliumClusterMeshConnectResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { 51 | resp.TypeName = req.ProviderTypeName + "_clustermesh_connection" 52 | } 53 | 54 | func (r *CiliumClusterMeshConnectResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { 55 | resp.Schema = schema.Schema{ 56 | // This description is used by the documentation generator and the language server. 57 | MarkdownDescription: "Cluster Mesh connection resource. This is equivalent to cilium cli: `cilium clustermesh connect` and `cilium clustermesh disconnect`: It manages the connections between two Kubernetes clusters.", 58 | 59 | Attributes: map[string]schema.Attribute{ 60 | "destination_contexts": schema.ListAttribute{ 61 | ElementType: types.StringType, 62 | MarkdownDescription: "Kubernetes configuration contexts of destination clusters", 63 | Optional: true, 64 | Computed: true, 65 | Default: listdefault.StaticValue(types.ListNull(types.StringType)), 66 | }, 67 | "parallel": schema.Int32Attribute{ 68 | MarkdownDescription: ConcatDefault("Number of parallel connections of destination clusters", "1"), 69 | Optional: true, 70 | Computed: true, 71 | Default: int32default.StaticInt32(1), 72 | }, 73 | "connection_mode": schema.StringAttribute{ 74 | MarkdownDescription: ConcatDefault("Connection mode. unicast, bidirectional and mesh", "bidirectional"), 75 | Optional: true, 76 | Computed: true, 77 | Default: stringdefault.StaticString("bidirectional"), 78 | }, 79 | //"destination_endpoint": schema.ListAttribute{ 80 | // ElementType: types.StringType, 81 | // MarkdownDescription: "IP of ClusterMesh service of destination cluster", 82 | // Optional: true, 83 | // Computed: true, 84 | //}, 85 | //"source_endpoint": schema.ListAttribute{ 86 | // ElementType: types.StringType, 87 | // MarkdownDescription: "IP of ClusterMesh service of source cluster", 88 | // Optional: true, 89 | // Computed: true, 90 | // Default: listdefault.StaticValue([]), 91 | //}, 92 | "id": schema.StringAttribute{ 93 | Computed: true, 94 | MarkdownDescription: "Cilium ClusterMesh Connection identifier", 95 | PlanModifiers: []planmodifier.String{ 96 | stringplanmodifier.UseStateForUnknown(), 97 | }, 98 | }, 99 | }, 100 | } 101 | } 102 | 103 | func (r *CiliumClusterMeshConnectResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { 104 | // Prevent panic if the provider has not been configured. 105 | if req.ProviderData == nil { 106 | return 107 | } 108 | 109 | client, ok := req.ProviderData.(*CiliumClient) 110 | 111 | if !ok { 112 | resp.Diagnostics.AddError( 113 | "Unexpected Resource Configure Type", 114 | fmt.Sprintf("Expected *CiliumClient, got: %T. Please report this issue to the provider developers.", req.ProviderData), 115 | ) 116 | 117 | return 118 | } 119 | 120 | r.client = client 121 | } 122 | 123 | func (r *CiliumClusterMeshConnectResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { 124 | var data CiliumClusterMeshConnectResourceModel 125 | c := r.client 126 | if c == nil { 127 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 128 | return 129 | } 130 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 131 | var params = clustermesh.Parameters{ 132 | Writer: os.Stdout, 133 | } 134 | 135 | // Read Terraform plan data into the model 136 | resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 137 | 138 | if resp.Diagnostics.HasError() { 139 | return 140 | } 141 | params.Namespace = namespace 142 | params.HelmReleaseName = helm_release 143 | 144 | params.DestinationContext = ValueList(ctx, data.DestinationContexts) 145 | params.ConnectionMode = data.ConnectionMode.ValueString() 146 | params.Parallel = int(data.Parallel.ValueInt32()) 147 | 148 | cm := clustermesh.NewK8sClusterMesh(k8sClient, params) 149 | if err := cm.ConnectWithHelm(context.Background()); err != nil { 150 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to connect cluster: %s", err)) 151 | return 152 | } 153 | 154 | // For the purposes of this example code, hardcoding a response value to 155 | // save into the Terraform state. 156 | data.Id = types.StringValue("ciliumclustermeshconnect-" + strings.Join(params.DestinationContext, "-")) 157 | 158 | // Write logs using the tflog package 159 | // Documentation: https://terraform.io/plugin/log 160 | tflog.Trace(ctx, "created a resource") 161 | 162 | // Save data into Terraform state 163 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 164 | } 165 | 166 | func (r *CiliumClusterMeshConnectResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { 167 | var data CiliumClusterMeshConnectResourceModel 168 | c := r.client 169 | if c == nil { 170 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 171 | return 172 | } 173 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 174 | var params = clustermesh.Parameters{ 175 | Writer: os.Stdout, 176 | } 177 | 178 | // Read Terraform prior state data into the model 179 | resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 180 | 181 | if resp.Diagnostics.HasError() { 182 | return 183 | } 184 | 185 | params.Namespace = namespace 186 | params.HelmReleaseName = helm_release 187 | params.Wait = true 188 | params.WaitDuration = 20 * time.Second 189 | 190 | cm := clustermesh.NewK8sClusterMesh(k8sClient, params) 191 | if _, err := cm.Status(context.Background()); err != nil { 192 | resp.State.RemoveResource(ctx) 193 | return 194 | } 195 | 196 | // Save updated data into Terraform state 197 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 198 | } 199 | 200 | func (r *CiliumClusterMeshConnectResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { 201 | var data CiliumClusterMeshConnectResourceModel 202 | c := r.client 203 | if c == nil { 204 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 205 | return 206 | } 207 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 208 | var params = clustermesh.Parameters{ 209 | Writer: os.Stdout, 210 | } 211 | 212 | // Read Terraform plan data into the model 213 | resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 214 | 215 | if resp.Diagnostics.HasError() { 216 | return 217 | } 218 | params.Namespace = namespace 219 | params.DestinationContext = ValueList(ctx, data.DestinationContexts) 220 | params.ConnectionMode = data.ConnectionMode.ValueString() 221 | params.HelmReleaseName = helm_release 222 | 223 | cm := clustermesh.NewK8sClusterMesh(k8sClient, params) 224 | if err := cm.ConnectWithHelm(context.Background()); err != nil { 225 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to connect clusters: %s", err)) 226 | return 227 | } 228 | 229 | // Save updated data into Terraform state 230 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 231 | } 232 | 233 | func (r *CiliumClusterMeshConnectResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { 234 | var data CiliumClusterMeshConnectResourceModel 235 | c := r.client 236 | if c == nil { 237 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 238 | return 239 | } 240 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 241 | var params = clustermesh.Parameters{ 242 | Writer: os.Stdout, 243 | } 244 | 245 | //// Read Terraform prior state data into the model 246 | resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 247 | 248 | if resp.Diagnostics.HasError() { 249 | return 250 | } 251 | 252 | params.Namespace = namespace 253 | params.HelmReleaseName = helm_release 254 | params.ConnectionMode = data.ConnectionMode.ValueString() 255 | params.DestinationContext = ValueList(ctx, data.DestinationContexts) 256 | 257 | cm := clustermesh.NewK8sClusterMesh(k8sClient, params) 258 | if err := cm.DisconnectWithHelm(context.Background()); err != nil { 259 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to disconnect clusters: %s", err)) 260 | return 261 | } 262 | } 263 | 264 | func (r *CiliumClusterMeshConnectResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { 265 | resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) 266 | } 267 | -------------------------------------------------------------------------------- /cilium/cluster_mesh_enable.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "os" 10 | "time" 11 | 12 | "github.com/cilium/cilium/cilium-cli/clustermesh" 13 | 14 | "github.com/hashicorp/terraform-plugin-framework/path" 15 | "github.com/hashicorp/terraform-plugin-framework/resource" 16 | "github.com/hashicorp/terraform-plugin-framework/resource/schema" 17 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" 18 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" 19 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" 20 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" 21 | "github.com/hashicorp/terraform-plugin-framework/types" 22 | "github.com/hashicorp/terraform-plugin-log/tflog" 23 | ) 24 | 25 | // Ensure provider defined types fully satisfy framework interfaces. 26 | var _ resource.Resource = &CiliumClusterMeshEnableResource{} 27 | var _ resource.ResourceWithImportState = &CiliumClusterMeshEnableResource{} 28 | 29 | func NewCiliumClusterMeshEnableResource() resource.Resource { 30 | return &CiliumClusterMeshEnableResource{} 31 | } 32 | 33 | // CiliumClusterMeshEnableResource defines the resource implementation. 34 | type CiliumClusterMeshEnableResource struct { 35 | client *CiliumClient 36 | } 37 | 38 | // CiliumClusterMeshEnableResourceModel describes the resource data model. 39 | type CiliumClusterMeshEnableResourceModel struct { 40 | EnableKVStoreMesh types.Bool `tfsdk:"enable_kv_store_mesh"` 41 | ServiceType types.String `tfsdk:"service_type"` 42 | Wait types.Bool `tfsdk:"wait"` 43 | Id types.String `tfsdk:"id"` 44 | } 45 | 46 | func (r *CiliumClusterMeshEnableResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { 47 | resp.TypeName = req.ProviderTypeName + "_clustermesh" 48 | } 49 | 50 | func (r *CiliumClusterMeshEnableResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { 51 | resp.Schema = schema.Schema{ 52 | // This description is used by the documentation generator and the language server. 53 | MarkdownDescription: "Cluster Mesh resource. This is equivalent to cilium cli: `cilium clustermesh enable` and `cilium clustermesh disable`: It manages the activation of Cluster Mesh on one Kubernetes cluster.", 54 | 55 | Attributes: map[string]schema.Attribute{ 56 | "enable_kv_store_mesh": schema.BoolAttribute{ 57 | MarkdownDescription: ConcatDefault("Enable kvstoremesh, an extension which caches remote cluster information in the local kvstore (Cilium >=1.14 only)", "false"), 58 | Optional: true, 59 | Computed: true, 60 | Default: booldefault.StaticBool(false), 61 | }, 62 | "service_type": schema.StringAttribute{ 63 | MarkdownDescription: ConcatDefault("Type of Kubernetes service to expose control plane { LoadBalancer | NodePort | ClusterIP }", "autodetected"), 64 | Optional: true, 65 | Computed: true, 66 | Default: stringdefault.StaticString(""), 67 | }, 68 | "wait": schema.BoolAttribute{ 69 | MarkdownDescription: ConcatDefault("Wait Cluster Mesh status is ok", "true"), 70 | Optional: true, 71 | Computed: true, 72 | Default: booldefault.StaticBool(true), 73 | }, 74 | "id": schema.StringAttribute{ 75 | Computed: true, 76 | MarkdownDescription: "Cilium ClusterMesh identifier", 77 | PlanModifiers: []planmodifier.String{ 78 | stringplanmodifier.UseStateForUnknown(), 79 | }, 80 | }, 81 | }, 82 | } 83 | } 84 | 85 | func (r *CiliumClusterMeshEnableResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { 86 | // Prevent panic if the provider has not been configured. 87 | if req.ProviderData == nil { 88 | return 89 | } 90 | 91 | client, ok := req.ProviderData.(*CiliumClient) 92 | 93 | if !ok { 94 | resp.Diagnostics.AddError( 95 | "Unexpected Resource Configure Type", 96 | fmt.Sprintf("Expected *CiliumClient, got: %T. Please report this issue to the provider developers.", req.ProviderData), 97 | ) 98 | 99 | return 100 | } 101 | 102 | r.client = client 103 | } 104 | 105 | func (r *CiliumClusterMeshEnableResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { 106 | var data CiliumClusterMeshEnableResourceModel 107 | c := r.client 108 | if c == nil { 109 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 110 | return 111 | } 112 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 113 | var params = clustermesh.Parameters{ 114 | Writer: os.Stdout, 115 | } 116 | 117 | // Read Terraform plan data into the model 118 | resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 119 | 120 | if resp.Diagnostics.HasError() { 121 | return 122 | } 123 | params.Namespace = namespace 124 | params.ServiceType = data.ServiceType.ValueString() 125 | params.EnableKVStoreMesh = data.EnableKVStoreMesh.ValueBool() // 126 | params.HelmReleaseName = helm_release 127 | wait := data.Wait.ValueBool() 128 | 129 | ctxb := context.Background() 130 | if err := clustermesh.EnableWithHelm(ctxb, k8sClient, params); err != nil { 131 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to enable ClusterMesh: %s", err)) 132 | return 133 | } 134 | 135 | if wait { 136 | if err := c.WaitClusterMesh(); err != nil { 137 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to enable ClusterMesh: %s", err)) 138 | return 139 | } 140 | } 141 | 142 | // For the purposes of this example code, hardcoding a response value to 143 | // save into the Terraform state. 144 | data.Id = types.StringValue("ciliumclustermeshenable") 145 | 146 | // Write logs using the tflog package 147 | // Documentation: https://terraform.io/plugin/log 148 | tflog.Trace(ctx, "created a resource") 149 | 150 | // Save data into Terraform state 151 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 152 | } 153 | 154 | func (r *CiliumClusterMeshEnableResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { 155 | var data CiliumClusterMeshEnableResourceModel 156 | var params = clustermesh.Parameters{ 157 | Writer: os.Stdout, 158 | } 159 | c := r.client 160 | if c == nil { 161 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 162 | return 163 | } 164 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 165 | 166 | // Read Terraform prior state data into the model 167 | resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 168 | 169 | if resp.Diagnostics.HasError() { 170 | return 171 | } 172 | 173 | params.Namespace = namespace 174 | params.Wait = true 175 | params.WaitDuration = 20 * time.Second 176 | params.HelmReleaseName = helm_release 177 | 178 | cm := clustermesh.NewK8sClusterMesh(k8sClient, params) 179 | if _, err := cm.Status(context.Background()); err != nil { 180 | fmt.Printf("Unable to determine status: %s\n", err) 181 | resp.State.RemoveResource(ctx) 182 | return 183 | } 184 | 185 | // Save updated data into Terraform state 186 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 187 | } 188 | 189 | func (r *CiliumClusterMeshEnableResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { 190 | var data CiliumClusterMeshEnableResourceModel 191 | c := r.client 192 | if c == nil { 193 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 194 | return 195 | } 196 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 197 | var params = clustermesh.Parameters{ 198 | Writer: os.Stdout, 199 | } 200 | 201 | // Read Terraform plan data into the model 202 | resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 203 | 204 | if resp.Diagnostics.HasError() { 205 | return 206 | } 207 | params.Namespace = namespace 208 | params.ServiceType = data.ServiceType.ValueString() 209 | params.EnableKVStoreMesh = data.EnableKVStoreMesh.ValueBool() // 210 | params.HelmReleaseName = helm_release 211 | wait := data.Wait.ValueBool() 212 | 213 | ctxb := context.Background() 214 | if err := clustermesh.EnableWithHelm(ctxb, k8sClient, params); err != nil { 215 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to enable ClusterMesh: %s", err)) 216 | return 217 | } 218 | 219 | if wait { 220 | if err := c.WaitClusterMesh(); err != nil { 221 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to enable ClusterMesh: %s", err)) 222 | return 223 | } 224 | } 225 | 226 | // Save updated data into Terraform state 227 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 228 | } 229 | 230 | func (r *CiliumClusterMeshEnableResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { 231 | var data CiliumClusterMeshEnableResourceModel 232 | c := r.client 233 | if c == nil { 234 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 235 | return 236 | } 237 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 238 | var params = clustermesh.Parameters{ 239 | Writer: os.Stdout, 240 | } 241 | 242 | //// Read Terraform prior state data into the model 243 | resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 244 | 245 | if resp.Diagnostics.HasError() { 246 | return 247 | } 248 | 249 | params.Namespace = namespace 250 | params.HelmReleaseName = helm_release 251 | ctxb := context.Background() 252 | 253 | if err := clustermesh.DisableWithHelm(ctxb, k8sClient, params); err != nil { 254 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to disable ClusterMesh: %s", err)) 255 | return 256 | } 257 | } 258 | 259 | func (r *CiliumClusterMeshEnableResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { 260 | resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) 261 | } 262 | -------------------------------------------------------------------------------- /cilium/cluster_mesh_enable_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "fmt" 8 | "testing" 9 | 10 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 11 | ) 12 | 13 | func TestAccCiliumClusterMeshEnableResource(t *testing.T) { 14 | resource.Test(t, resource.TestCase{ 15 | PreCheck: func() { testAccPreCheck(t) }, 16 | ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, 17 | Steps: []resource.TestStep{ 18 | // Create and Read testing 19 | { 20 | Config: testAccCiliumClusterMeshEnableResourceConfig("NodePort"), 21 | Check: resource.ComposeAggregateTestCheckFunc( 22 | resource.TestCheckResourceAttr("cilium_clustermesh.test", "enable_kv_store_mesh", "false"), 23 | resource.TestCheckResourceAttr("cilium_clustermesh.test", "service_type", "NodePort"), 24 | resource.TestCheckResourceAttr("cilium_clustermesh.test", "id", "ciliumclustermeshenable"), 25 | ), 26 | }, 27 | // ImportState testing 28 | //{ 29 | // ResourceName: "cilium_clustermesh.test", 30 | // ImportState: true, 31 | // ImportStateVerify: true, 32 | // ImportStateVerifyIgnore: []string{"enable_external_workloads", "enable_kv_store_mesh", "service_type"}, 33 | //}, 34 | // Delete testing automatically occurs in TestCase 35 | }, 36 | }) 37 | } 38 | 39 | func testAccCiliumClusterMeshEnableResourceConfig(service_type string) string { 40 | return fmt.Sprintf(` 41 | resource "cilium" "test" { 42 | version = "1.15.8" 43 | } 44 | resource "cilium_clustermesh" "test" { 45 | service_type = %[1]q 46 | depends_on = [ cilium.test ] 47 | } 48 | `, service_type) 49 | } 50 | -------------------------------------------------------------------------------- /cilium/config.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "context" 8 | "encoding/json" 9 | "fmt" 10 | "os" 11 | "regexp" 12 | 13 | "github.com/cilium/cilium/cilium-cli/config" 14 | 15 | "github.com/hashicorp/terraform-plugin-framework/path" 16 | "github.com/hashicorp/terraform-plugin-framework/resource" 17 | "github.com/hashicorp/terraform-plugin-framework/resource/schema" 18 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" 19 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" 20 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" 21 | "github.com/hashicorp/terraform-plugin-framework/types" 22 | "github.com/hashicorp/terraform-plugin-log/tflog" 23 | ) 24 | 25 | // Ensure provider defined types fully satisfy framework interfaces. 26 | var _ resource.Resource = &CiliumConfigResource{} 27 | var _ resource.ResourceWithImportState = &CiliumConfigResource{} 28 | 29 | func NewCiliumConfigResource() resource.Resource { 30 | return &CiliumConfigResource{} 31 | } 32 | 33 | // CiliumConfigResource defines the resource implementation. 34 | type CiliumConfigResource struct { 35 | client *CiliumClient 36 | } 37 | 38 | // CiliumConfigResourceModel describes the resource data model. 39 | type CiliumConfigResourceModel struct { 40 | Restart types.Bool `tfsdk:"restart"` 41 | Key types.String `tfsdk:"key"` 42 | Value types.String `tfsdk:"value"` 43 | Id types.String `tfsdk:"id"` 44 | } 45 | 46 | func (r *CiliumConfigResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { 47 | resp.TypeName = req.ProviderTypeName + "_config" 48 | } 49 | 50 | func (r *CiliumConfigResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { 51 | resp.Schema = schema.Schema{ 52 | // This description is used by the documentation generator and the language server. 53 | MarkdownDescription: "Config resource for Cilium. This is equivalent to cilium cli: `cilium config`: It manages the cilium Kubernetes ConfigMap resource", 54 | 55 | Attributes: map[string]schema.Attribute{ 56 | "restart": schema.BoolAttribute{ 57 | MarkdownDescription: ConcatDefault("Restart Cilium pods", "true"), 58 | Optional: true, 59 | Computed: true, 60 | Default: booldefault.StaticBool(true), 61 | }, 62 | "key": schema.StringAttribute{ 63 | MarkdownDescription: "Key of the config", 64 | Required: true, 65 | }, 66 | "value": schema.StringAttribute{ 67 | MarkdownDescription: "Value of the key", 68 | Required: true, 69 | }, 70 | "id": schema.StringAttribute{ 71 | Computed: true, 72 | MarkdownDescription: "Cilium config identifier", 73 | PlanModifiers: []planmodifier.String{ 74 | stringplanmodifier.UseStateForUnknown(), 75 | }, 76 | }, 77 | }, 78 | } 79 | } 80 | 81 | func (r *CiliumConfigResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { 82 | // Prevent panic if the provider has not been configured. 83 | if req.ProviderData == nil { 84 | return 85 | } 86 | 87 | client, ok := req.ProviderData.(*CiliumClient) 88 | 89 | if !ok { 90 | resp.Diagnostics.AddError( 91 | "Unexpected Resource Configure Type", 92 | fmt.Sprintf("Expected *CiliumClient, got: %T. Please report this issue to the provider developers.", req.ProviderData), 93 | ) 94 | 95 | return 96 | } 97 | 98 | r.client = client 99 | } 100 | 101 | func (r *CiliumConfigResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { 102 | var data CiliumConfigResourceModel 103 | c := r.client 104 | if c == nil { 105 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 106 | return 107 | } 108 | k8sClient, namespace := c.client, c.namespace 109 | var params = config.Parameters{ 110 | Writer: os.Stdout, 111 | } 112 | 113 | // Read Terraform plan data into the model 114 | resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 115 | 116 | if resp.Diagnostics.HasError() { 117 | return 118 | } 119 | key := data.Key.ValueString() 120 | value := data.Value.ValueString() 121 | params.Namespace = namespace 122 | params.Restart = data.Restart.ValueBool() 123 | 124 | check := config.NewK8sConfig(k8sClient, params) 125 | if err := check.Set(context.Background(), key, value, params); err != nil { 126 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to set config: %s", err)) 127 | return 128 | } 129 | 130 | // For the purposes of this example code, hardcoding a response value to 131 | // save into the Terraform state. 132 | data.Id = types.StringValue("cilium-config-" + key) 133 | 134 | // Write logs using the tflog package 135 | // Documentation: https://terraform.io/plugin/log 136 | tflog.Trace(ctx, "created a resource") 137 | 138 | // Save data into Terraform state 139 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 140 | } 141 | 142 | func (r *CiliumConfigResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { 143 | var data CiliumConfigResourceModel 144 | c := r.client 145 | if c == nil { 146 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 147 | return 148 | } 149 | k8sClient, namespace := c.client, c.namespace 150 | var params = config.Parameters{ 151 | Writer: os.Stdout, 152 | } 153 | 154 | // Read Terraform prior state data into the model 155 | resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 156 | 157 | if resp.Diagnostics.HasError() { 158 | return 159 | } 160 | params.Namespace = namespace 161 | key := data.Key.ValueString() 162 | value := data.Value.ValueString() 163 | 164 | readReq := CiliumConfigResourceModel{ 165 | Id: data.Id, 166 | Value: data.Value, 167 | Key: data.Key, 168 | Restart: data.Restart, 169 | } 170 | 171 | _, err := json.Marshal(readReq) 172 | 173 | if err != nil { 174 | resp.Diagnostics.AddError( 175 | "Unable to Refresh Resource", 176 | "An unexpected error occurred while creating the resource read request. "+ 177 | "Please report this issue to the provider developers.\n\n"+ 178 | "JSON Error: "+err.Error(), 179 | ) 180 | 181 | return 182 | } 183 | 184 | check := config.NewK8sConfig(k8sClient, params) 185 | out, err := check.View(context.Background()) 186 | if err != nil { 187 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to view config: %s", err)) 188 | return 189 | } 190 | 191 | m, err := regexp.MatchString(key+".*"+value, out) 192 | if err != nil { 193 | fmt.Println("your regex is faulty") 194 | return 195 | } 196 | if m { 197 | fmt.Println("Ok") 198 | } else { 199 | resp.State.RemoveResource(ctx) 200 | return 201 | } 202 | 203 | // Save updated data into Terraform state 204 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 205 | } 206 | 207 | func (r *CiliumConfigResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { 208 | var data CiliumConfigResourceModel 209 | c := r.client 210 | if c == nil { 211 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 212 | return 213 | } 214 | k8sClient, namespace := c.client, c.namespace 215 | var params = config.Parameters{ 216 | Writer: os.Stdout, 217 | } 218 | 219 | // Read Terraform plan data into the model 220 | resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 221 | 222 | if resp.Diagnostics.HasError() { 223 | return 224 | } 225 | 226 | key := data.Key.ValueString() 227 | value := data.Value.ValueString() 228 | params.Namespace = namespace 229 | params.Restart = data.Restart.ValueBool() 230 | 231 | check := config.NewK8sConfig(k8sClient, params) 232 | if err := check.Set(context.Background(), key, value, params); err != nil { 233 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to set config: %s", err)) 234 | return 235 | } 236 | 237 | // Save updated data into Terraform state 238 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 239 | } 240 | 241 | func (r *CiliumConfigResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { 242 | var data CiliumConfigResourceModel 243 | c := r.client 244 | if c == nil { 245 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 246 | return 247 | } 248 | k8sClient, namespace := c.client, c.namespace 249 | var params = config.Parameters{ 250 | Writer: os.Stdout, 251 | } 252 | 253 | // Read Terraform prior state data into the model 254 | resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 255 | 256 | if resp.Diagnostics.HasError() { 257 | return 258 | } 259 | 260 | params.Namespace = namespace 261 | key := data.Key.ValueString() 262 | params.Restart = data.Restart.ValueBool() 263 | 264 | check := config.NewK8sConfig(k8sClient, params) 265 | if err := check.Delete(context.Background(), key, params); err != nil { 266 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to delete config: %s", err)) 267 | return 268 | } 269 | } 270 | 271 | func (r *CiliumConfigResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { 272 | resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) 273 | } 274 | -------------------------------------------------------------------------------- /cilium/config_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "fmt" 8 | "testing" 9 | 10 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 11 | ) 12 | 13 | func TestAccCiliumConfigResource(t *testing.T) { 14 | resource.Test(t, resource.TestCase{ 15 | PreCheck: func() { testAccPreCheck(t) }, 16 | ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, 17 | Steps: []resource.TestStep{ 18 | // Create and Read testing 19 | { 20 | Config: testAccCiliumConfigResourceConfig("debug", "true"), 21 | Check: resource.ComposeAggregateTestCheckFunc( 22 | resource.TestCheckResourceAttr("cilium_config.test", "key", "debug"), 23 | resource.TestCheckResourceAttr("cilium_config.test", "value", "true"), 24 | resource.TestCheckResourceAttr("cilium_config.test", "restart", "true"), 25 | resource.TestCheckResourceAttr("cilium_config.test", "id", "cilium-config-debug"), 26 | ), 27 | }, 28 | // ImportState testing 29 | //{ 30 | // ResourceName: "cilium_clustermesh.test", 31 | // ImportState: true, 32 | // ImportStateVerify: true, 33 | // ImportStateVerifyIgnore: []string{"enable_external_workloads", "enable_kv_store_mesh", "service_type"}, 34 | //}, 35 | // Delete testing automatically occurs in TestCase 36 | }, 37 | }) 38 | } 39 | 40 | func testAccCiliumConfigResourceConfig(key string, value string) string { 41 | return fmt.Sprintf(` 42 | resource "cilium" "test" { 43 | version = "1.16.1" 44 | } 45 | resource "cilium_config" "test" { 46 | key = %[1]q 47 | value = %[2]q 48 | depends_on = [ cilium.test ] 49 | } 50 | `, key, value) 51 | } 52 | -------------------------------------------------------------------------------- /cilium/data_helm_values.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | 10 | "gopkg.in/yaml.v3" 11 | "helm.sh/helm/v3/pkg/action" 12 | 13 | "github.com/hashicorp/terraform-plugin-framework/datasource" 14 | "github.com/hashicorp/terraform-plugin-framework/datasource/schema" 15 | "github.com/hashicorp/terraform-plugin-framework/types" 16 | "github.com/hashicorp/terraform-plugin-log/tflog" 17 | ) 18 | 19 | // Ensure provider defined types fully satisfy framework interfaces. 20 | var _ datasource.DataSource = &CiliumHelmValuesDataSource{} 21 | 22 | func NewCiliumHelmValuesDataSource() datasource.DataSource { 23 | return &CiliumHelmValuesDataSource{} 24 | } 25 | 26 | // ExampleDataSource defines the data source implementation. 27 | type CiliumHelmValuesDataSource struct { 28 | client *CiliumClient 29 | } 30 | 31 | // ExampleDataSourceModel describes the data source data model. 32 | type CiliumHelmValuesDataSourceModel struct { 33 | Yaml types.String `tfsdk:"yaml"` 34 | } 35 | 36 | func (d *CiliumHelmValuesDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { 37 | resp.TypeName = req.ProviderTypeName + "_helm_values" 38 | } 39 | 40 | func (d *CiliumHelmValuesDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { 41 | resp.Schema = schema.Schema{ 42 | // This description is used by the documentation generator and the language server. 43 | MarkdownDescription: "Helm values of cilium", 44 | 45 | Attributes: map[string]schema.Attribute{ 46 | "yaml": schema.StringAttribute{ 47 | MarkdownDescription: "Yaml output", 48 | Computed: true, 49 | }, 50 | }, 51 | } 52 | } 53 | 54 | func (d *CiliumHelmValuesDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { 55 | // Prevent panic if the provider has not been configured. 56 | if req.ProviderData == nil { 57 | return 58 | } 59 | 60 | client, ok := req.ProviderData.(*CiliumClient) 61 | 62 | if !ok { 63 | resp.Diagnostics.AddError( 64 | "Unexpected Data Source Configure Type", 65 | fmt.Sprintf("Expected *CiliumClient, got: %T. Please report this issue to the provider developers.", req.ProviderData), 66 | ) 67 | 68 | return 69 | } 70 | 71 | d.client = client 72 | } 73 | 74 | func (d *CiliumHelmValuesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { 75 | var data CiliumHelmValuesDataSourceModel 76 | c := d.client 77 | if c == nil { 78 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 79 | return 80 | } 81 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 82 | 83 | // Read Terraform configuration data into the model 84 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 85 | 86 | if resp.Diagnostics.HasError() { 87 | return 88 | } 89 | actionConfig := action.Configuration{} 90 | logger := func(format string, v ...interface{}) {} 91 | helmDriver := "" 92 | if err := actionConfig.Init(k8sClient.RESTClientGetter, namespace, helmDriver, logger); err != nil { 93 | return 94 | } 95 | 96 | client := action.NewGetValues(&actionConfig) 97 | 98 | vals, err := client.Run(helm_release) 99 | 100 | if err != nil { 101 | return 102 | } 103 | 104 | // For the purposes of this example code, hardcoding a response value to 105 | // save into the Terraform state. 106 | yaml, err := yaml.Marshal(vals) 107 | if err != nil { 108 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed: %s", err)) 109 | return 110 | } 111 | 112 | data.Yaml = types.StringValue(string(yaml)) 113 | 114 | // Write logs using the tflog package 115 | // Documentation: https://terraform.io/plugin/log 116 | tflog.Trace(ctx, "read a data source") 117 | 118 | // Save data into Terraform state 119 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 120 | } 121 | -------------------------------------------------------------------------------- /cilium/data_helm_values_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 10 | ) 11 | 12 | func TestAccCiliumHelmValuesDataSource(t *testing.T) { 13 | resource.Test(t, resource.TestCase{ 14 | PreCheck: func() { testAccPreCheck(t) }, 15 | ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, 16 | Steps: []resource.TestStep{ 17 | // Create and Read testing 18 | { 19 | Config: testAccCiliumHelmValuesDataSourceConfig(), 20 | Check: resource.ComposeAggregateTestCheckFunc( 21 | resource.TestCheckResourceAttr("data.cilium_helm_values.test", "yaml", "cluster:\n name: kind-chart-testing\nipam:\n mode: kubernetes\noperator:\n replicas: 1\nroutingMode: tunnel\ntunnelProtocol: vxlan\n"), 22 | ), 23 | }, 24 | // Delete testing automatically occurs in TestCase 25 | }, 26 | }) 27 | } 28 | 29 | func testAccCiliumHelmValuesDataSourceConfig() string { 30 | return ` 31 | resource "cilium" "test" { 32 | version = "1.16.1" 33 | } 34 | 35 | data "cilium_helm_values" "test" { 36 | 37 | depends_on = [ 38 | cilium.test 39 | ] 40 | } 41 | ` 42 | } 43 | -------------------------------------------------------------------------------- /cilium/helper.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | import ( 4 | "context" 5 | "encoding/base64" 6 | "fmt" 7 | "os" 8 | "time" 9 | 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 | 12 | "github.com/cilium/cilium/cilium-cli/clustermesh" 13 | "github.com/cilium/cilium/cilium-cli/defaults" 14 | "github.com/cilium/cilium/cilium-cli/k8s" 15 | "github.com/cilium/cilium/cilium-cli/status" 16 | 17 | "gopkg.in/yaml.v3" 18 | "helm.sh/helm/v3/pkg/action" 19 | "helm.sh/helm/v3/pkg/release" 20 | 21 | "github.com/hashicorp/terraform-plugin-framework/attr" 22 | "github.com/hashicorp/terraform-plugin-framework/types" 23 | ) 24 | 25 | var CaAttributeTypes = map[string]attr.Type{ 26 | "crt": types.StringType, 27 | "key": types.StringType, 28 | } 29 | 30 | type CiliumClient struct { 31 | client *k8s.Client 32 | namespace string 33 | helm_release string 34 | } 35 | 36 | func ConcatDefault(text string, d string) string { 37 | return fmt.Sprintf("%s (Default: `%s`).", text, d) 38 | } 39 | 40 | func (c *CiliumClient) Wait() (err error) { 41 | var status_params = status.K8sStatusParameters{} 42 | status_params.Namespace = c.namespace 43 | status_params.Wait = true 44 | status_params.WaitDuration = defaults.StatusWaitDuration 45 | collector, err := status.NewK8sStatusCollector(c.client, status_params) 46 | if err != nil { 47 | return err 48 | } 49 | _, err = collector.Status(context.Background()) 50 | return err 51 | } 52 | 53 | func (c *CiliumClient) GetCurrentRelease() (*release.Release, error) { 54 | // Use the default Helm driver (Kubernetes secret). 55 | helmDriver := "" 56 | actionConfig := action.Configuration{} 57 | logger := func(format string, v ...interface{}) {} 58 | if err := actionConfig.Init(c.client.RESTClientGetter, c.namespace, helmDriver, logger); err != nil { 59 | return nil, err 60 | } 61 | currentRelease, err := actionConfig.Releases.Last(c.helm_release) 62 | if err != nil { 63 | return nil, err 64 | } 65 | return currentRelease, nil 66 | } 67 | 68 | func (c *CiliumClient) GetHelmValues() (string, error) { 69 | helmDriver := "" 70 | actionConfig := action.Configuration{} 71 | logger := func(format string, v ...interface{}) {} 72 | if err := actionConfig.Init(c.client.RESTClientGetter, c.namespace, helmDriver, logger); err != nil { 73 | return "", err 74 | } 75 | client := action.NewGetValues(&actionConfig) 76 | 77 | vals, err := client.Run(c.helm_release) 78 | if err != nil { 79 | return "", err 80 | } 81 | 82 | yaml, err := yaml.Marshal(vals) 83 | if err != nil { 84 | return "", err 85 | } 86 | return string(yaml), nil 87 | } 88 | 89 | func (c *CiliumClient) GetCA(ctx context.Context) (map[string]attr.Value, error) { 90 | k8sClient := c.client 91 | s, err := k8sClient.GetSecret(ctx, c.namespace, "cilium-ca", metav1.GetOptions{}) 92 | if err != nil { 93 | return map[string]attr.Value{}, err 94 | } 95 | ca := map[string]attr.Value{ 96 | "key": types.StringValue(base64.StdEncoding.EncodeToString(s.Data["ca.key"])), 97 | "crt": types.StringValue(base64.StdEncoding.EncodeToString(s.Data["ca.crt"])), 98 | } 99 | 100 | return ca, nil 101 | } 102 | 103 | func (c *CiliumClient) GetMetadata() (string, error) { 104 | helmDriver := "" 105 | actionConfig := action.Configuration{} 106 | logger := func(format string, v ...interface{}) {} 107 | if err := actionConfig.Init(c.client.RESTClientGetter, c.namespace, helmDriver, logger); err != nil { 108 | return "", err 109 | } 110 | client := action.NewGetMetadata(&actionConfig) 111 | 112 | vals, err := client.Run(c.helm_release) 113 | if err != nil { 114 | return "", err 115 | } 116 | 117 | return vals.AppVersion, nil 118 | } 119 | 120 | func (c *CiliumClient) WaitClusterMesh() (err error) { 121 | var params = clustermesh.Parameters{Writer: os.Stdout} 122 | params.Namespace = c.namespace 123 | params.Wait = true 124 | params.WaitDuration = 2 * time.Minute 125 | cm := clustermesh.NewK8sClusterMesh(c.client, params) 126 | if _, err := cm.Status(context.Background()); err != nil { 127 | return err 128 | } 129 | return nil 130 | } 131 | 132 | func (c *CiliumClient) CheckDaemonsetStatus(ctx context.Context, namespace, daemonset string) error { 133 | k8sClient := c.client 134 | d, _ := k8sClient.GetDaemonSet(ctx, namespace, daemonset, metav1.GetOptions{}) 135 | if d == nil { 136 | return nil 137 | } 138 | 139 | if d.Status.NumberReady != 0 { 140 | return fmt.Errorf("replicas count is not zero") 141 | } 142 | 143 | return nil 144 | } 145 | 146 | func (c *CiliumClient) CheckDaemonsetAvailability(ctx context.Context, namespace, daemonset string) error { 147 | k8sClient := c.client 148 | d, err := k8sClient.GetDaemonSet(ctx, namespace, daemonset, metav1.GetOptions{}) 149 | if err != nil { 150 | return err 151 | } 152 | 153 | if d == nil { 154 | return fmt.Errorf("daemonset is not available") 155 | } 156 | 157 | return nil 158 | } 159 | 160 | func ValueList(ctx context.Context, l types.List) []string { 161 | destinationContexts := make([]types.String, 0, len(l.Elements())) 162 | l.ElementsAs(ctx, &destinationContexts, false) 163 | 164 | d := []string{} 165 | for _, e := range destinationContexts { 166 | d = append(d, e.ValueString()) 167 | } 168 | return d 169 | } 170 | -------------------------------------------------------------------------------- /cilium/hubble.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "os" 10 | 11 | "github.com/cilium/cilium/cilium-cli/hubble" 12 | 13 | "github.com/hashicorp/terraform-plugin-framework/path" 14 | "github.com/hashicorp/terraform-plugin-framework/resource" 15 | "github.com/hashicorp/terraform-plugin-framework/resource/schema" 16 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" 17 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" 18 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" 19 | "github.com/hashicorp/terraform-plugin-framework/types" 20 | "github.com/hashicorp/terraform-plugin-log/tflog" 21 | ) 22 | 23 | // Ensure provider defined types fully satisfy framework interfaces. 24 | var _ resource.Resource = &CiliumHubbleResource{} 25 | var _ resource.ResourceWithImportState = &CiliumHubbleResource{} 26 | 27 | func NewCiliumHubbleResource() resource.Resource { 28 | return &CiliumHubbleResource{} 29 | } 30 | 31 | // CiliumHubbleResource defines the resource implementation. 32 | type CiliumHubbleResource struct { 33 | client *CiliumClient 34 | } 35 | 36 | // CiliumHubbleResourceModel describes the resource data model. 37 | type CiliumHubbleResourceModel struct { 38 | Relay types.Bool `tfsdk:"relay"` 39 | UI types.Bool `tfsdk:"ui"` 40 | Id types.String `tfsdk:"id"` 41 | } 42 | 43 | func (r *CiliumHubbleResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { 44 | resp.TypeName = req.ProviderTypeName + "_hubble" 45 | } 46 | 47 | func (r *CiliumHubbleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { 48 | resp.Schema = schema.Schema{ 49 | // This description is used by the documentation generator and the language server. 50 | MarkdownDescription: "Hubble resource for Cilium. This is equivalent to cilium cli: `cilium hubble`: It manages cilium hubble", 51 | 52 | Attributes: map[string]schema.Attribute{ 53 | "ui": schema.BoolAttribute{ 54 | MarkdownDescription: ConcatDefault("Enable Hubble UI", "false"), 55 | Optional: true, 56 | Computed: true, 57 | Default: booldefault.StaticBool(false), 58 | }, 59 | "relay": schema.BoolAttribute{ 60 | MarkdownDescription: ConcatDefault("Deploy Hubble Relay", "true"), 61 | Optional: true, 62 | Computed: true, 63 | Default: booldefault.StaticBool(true), 64 | }, 65 | "id": schema.StringAttribute{ 66 | Computed: true, 67 | MarkdownDescription: "Cilium hubble identifier", 68 | PlanModifiers: []planmodifier.String{ 69 | stringplanmodifier.UseStateForUnknown(), 70 | }, 71 | }, 72 | }, 73 | } 74 | } 75 | 76 | func (r *CiliumHubbleResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { 77 | // Prevent panic if the provider has not been configured. 78 | if req.ProviderData == nil { 79 | return 80 | } 81 | 82 | client, ok := req.ProviderData.(*CiliumClient) 83 | 84 | if !ok { 85 | resp.Diagnostics.AddError( 86 | "Unexpected Resource Configure Type", 87 | fmt.Sprintf("Expected *CiliumClient, got: %T. Please report this issue to the provider developers.", req.ProviderData), 88 | ) 89 | 90 | return 91 | } 92 | 93 | r.client = client 94 | } 95 | 96 | func (r *CiliumHubbleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { 97 | var data CiliumHubbleResourceModel 98 | c := r.client 99 | if c == nil { 100 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 101 | return 102 | } 103 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 104 | var params = hubble.Parameters{Writer: os.Stdout} 105 | 106 | // Read Terraform plan data into the model 107 | resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 108 | 109 | if resp.Diagnostics.HasError() { 110 | return 111 | } 112 | params.Namespace = namespace 113 | params.UI = data.UI.ValueBool() 114 | params.Relay = data.Relay.ValueBool() 115 | params.HelmReleaseName = helm_release 116 | 117 | if err := hubble.EnableWithHelm(context.Background(), k8sClient, params); err != nil { 118 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to enable Hubble: %s", err)) 119 | return 120 | } 121 | // For the purposes of this example code, hardcoding a response value to 122 | // save into the Terraform state. 123 | data.Id = types.StringValue("cilium-hubble") 124 | 125 | // Write logs using the tflog package 126 | // Documentation: https://terraform.io/plugin/log 127 | tflog.Trace(ctx, "created a resource") 128 | 129 | // Save data into Terraform state 130 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 131 | } 132 | 133 | func (r *CiliumHubbleResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { 134 | var data CiliumHubbleResourceModel 135 | 136 | // Read Terraform prior state data into the model 137 | resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 138 | 139 | if resp.Diagnostics.HasError() { 140 | return 141 | } 142 | 143 | // Save updated data into Terraform state 144 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 145 | } 146 | 147 | func (r *CiliumHubbleResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { 148 | var data CiliumHubbleResourceModel 149 | c := r.client 150 | if c == nil { 151 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 152 | return 153 | } 154 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 155 | var params = hubble.Parameters{Writer: os.Stdout} 156 | 157 | // Read Terraform plan data into the model 158 | resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 159 | 160 | if resp.Diagnostics.HasError() { 161 | return 162 | } 163 | 164 | params.Namespace = namespace 165 | params.UI = data.UI.ValueBool() 166 | params.Relay = data.Relay.ValueBool() 167 | params.HelmReleaseName = helm_release 168 | 169 | if err := hubble.EnableWithHelm(context.Background(), k8sClient, params); err != nil { 170 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update Hubble: %s", err)) 171 | return 172 | } 173 | 174 | // Save updated data into Terraform state 175 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 176 | } 177 | 178 | func (r *CiliumHubbleResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { 179 | var data CiliumHubbleResourceModel 180 | c := r.client 181 | if c == nil { 182 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 183 | return 184 | } 185 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 186 | var params = hubble.Parameters{Writer: os.Stdout} 187 | 188 | // Read Terraform prior state data into the model 189 | resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 190 | 191 | if resp.Diagnostics.HasError() { 192 | return 193 | } 194 | 195 | params.Namespace = namespace 196 | params.HelmReleaseName = helm_release 197 | 198 | if err := hubble.DisableWithHelm(context.Background(), k8sClient, params); err != nil { 199 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to disable Hubble: %s", err)) 200 | return 201 | } 202 | } 203 | 204 | func (r *CiliumHubbleResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { 205 | resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) 206 | } 207 | -------------------------------------------------------------------------------- /cilium/hubble_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "fmt" 8 | "testing" 9 | 10 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 11 | ) 12 | 13 | func TestAccCiliumHubbleResource(t *testing.T) { 14 | resource.Test(t, resource.TestCase{ 15 | PreCheck: func() { testAccPreCheck(t) }, 16 | ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, 17 | Steps: []resource.TestStep{ 18 | // Create and Read testing 19 | { 20 | Config: testAccCiliumHubbleResourceConfig("true"), 21 | Check: resource.ComposeAggregateTestCheckFunc( 22 | resource.TestCheckResourceAttr("cilium_hubble.test", "ui", "true"), 23 | resource.TestCheckResourceAttr("cilium_hubble.test", "relay", "true"), 24 | resource.TestCheckResourceAttr("cilium_hubble.test", "id", "cilium-hubble"), 25 | ), 26 | }, 27 | // ImportState testing 28 | //{ 29 | // ResourceName: "cilium_clustermesh.test", 30 | // ImportState: true, 31 | // ImportStateVerify: true, 32 | // ImportStateVerifyIgnore: []string{"enable_external_workloads", "enable_kv_store_mesh", "service_type"}, 33 | //}, 34 | // Delete testing automatically occurs in TestCase 35 | }, 36 | }) 37 | } 38 | 39 | func testAccCiliumHubbleResourceConfig(ui string) string { 40 | return fmt.Sprintf(` 41 | resource "cilium" "test" { 42 | version = "1.16.1" 43 | } 44 | resource "cilium_hubble" "test" { 45 | ui = %s 46 | depends_on = [ cilium.test ] 47 | } 48 | `, ui) 49 | } 50 | -------------------------------------------------------------------------------- /cilium/install.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | "os" 10 | "time" 11 | 12 | "github.com/cilium/cilium/cilium-cli/defaults" 13 | "github.com/cilium/cilium/cilium-cli/install" 14 | 15 | "helm.sh/helm/v3/pkg/cli/values" 16 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 17 | 18 | "github.com/hashicorp/terraform-plugin-framework/path" 19 | "github.com/hashicorp/terraform-plugin-framework/resource" 20 | "github.com/hashicorp/terraform-plugin-framework/resource/schema" 21 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" 22 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/listdefault" 23 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" 24 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" 25 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" 26 | "github.com/hashicorp/terraform-plugin-framework/types" 27 | "github.com/hashicorp/terraform-plugin-log/tflog" 28 | ) 29 | 30 | // Ensure provider defined types fully satisfy framework interfaces. 31 | var _ resource.Resource = &CiliumInstallResource{} 32 | var _ resource.ResourceWithImportState = &CiliumInstallResource{} 33 | 34 | func NewCiliumInstallResource() resource.Resource { 35 | return &CiliumInstallResource{} 36 | } 37 | 38 | // CiliumInstallResource defines the resource implementation. 39 | type CiliumInstallResource struct { 40 | client *CiliumClient 41 | } 42 | 43 | // CiliumInstallResourceModel describes the resource data model. 44 | type CiliumInstallResourceModel struct { 45 | HelmSet types.List `tfsdk:"set"` 46 | Values types.String `tfsdk:"values"` 47 | Version types.String `tfsdk:"version"` 48 | Repository types.String `tfsdk:"repository"` 49 | DataPath types.String `tfsdk:"data_path"` 50 | Wait types.Bool `tfsdk:"wait"` 51 | Reuse types.Bool `tfsdk:"reuse"` 52 | Reset types.Bool `tfsdk:"reset"` 53 | Id types.String `tfsdk:"id"` 54 | HelmValues types.String `tfsdk:"helm_values"` 55 | CA types.Object `tfsdk:"ca"` 56 | } 57 | 58 | func (r *CiliumInstallResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { 59 | resp.TypeName = req.ProviderTypeName 60 | } 61 | 62 | func (r *CiliumInstallResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { 63 | resp.Schema = schema.Schema{ 64 | // This description is used by the documentation generator and the language server. 65 | MarkdownDescription: "Install resource for Cilium. This is equivalent to cilium cli: `cilium install`, `cilium upgrade` and `cilium uninstall`: It manages cilium helm chart", 66 | 67 | Attributes: map[string]schema.Attribute{ 68 | "ca": schema.ObjectAttribute{ 69 | AttributeTypes: CaAttributeTypes, 70 | Computed: true, 71 | Sensitive: true, 72 | }, 73 | "set": schema.ListAttribute{ 74 | ElementType: types.StringType, 75 | MarkdownDescription: ConcatDefault("Set helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2", "[]"), 76 | Optional: true, 77 | Computed: true, 78 | Default: listdefault.StaticValue(types.ListNull(types.StringType)), 79 | }, 80 | "values": schema.StringAttribute{ 81 | MarkdownDescription: ConcatDefault("values in raw yaml to pass to helm.", "empty"), 82 | Optional: true, 83 | Computed: true, 84 | Default: stringdefault.StaticString(""), 85 | }, 86 | "version": schema.StringAttribute{ 87 | MarkdownDescription: ConcatDefault("Version of Cilium", "1.17.3"), 88 | Optional: true, 89 | Computed: true, 90 | Default: stringdefault.StaticString("1.17.3"), 91 | }, 92 | "repository": schema.StringAttribute{ 93 | MarkdownDescription: ConcatDefault("Helm chart repository to download Cilium charts from", defaults.HelmRepository), 94 | Optional: true, 95 | Computed: true, 96 | Default: stringdefault.StaticString(defaults.HelmRepository), 97 | }, 98 | "data_path": schema.StringAttribute{ 99 | MarkdownDescription: ConcatDefault("Datapath mode to use { tunnel | native | aws-eni | gke | azure | aks-byocni }", "autodetected"), 100 | Optional: true, 101 | Computed: true, 102 | Default: stringdefault.StaticString(""), 103 | }, 104 | "reuse": schema.BoolAttribute{ 105 | MarkdownDescription: ConcatDefault("When upgrading, reuse the helm values from the latest release unless any overrides from are set from other flags. This option takes precedence over HelmResetValues", "true"), 106 | Optional: true, 107 | Computed: true, 108 | Default: booldefault.StaticBool(true), 109 | }, 110 | "reset": schema.BoolAttribute{ 111 | MarkdownDescription: ConcatDefault("When upgrading, reset the helm values to the ones built into the chart", "false"), 112 | Optional: true, 113 | Computed: true, 114 | Default: booldefault.StaticBool(false), 115 | }, 116 | "wait": schema.BoolAttribute{ 117 | MarkdownDescription: ConcatDefault("Wait for Cilium status is ok", "true"), 118 | Optional: true, 119 | Computed: true, 120 | Default: booldefault.StaticBool(true), 121 | }, 122 | "id": schema.StringAttribute{ 123 | Computed: true, 124 | MarkdownDescription: "Cilium install identifier", 125 | PlanModifiers: []planmodifier.String{ 126 | stringplanmodifier.UseStateForUnknown(), 127 | }, 128 | }, 129 | "helm_values": schema.StringAttribute{ 130 | Computed: true, 131 | MarkdownDescription: "Helm values (`helm get values -n kube-system cilium`)", 132 | }, 133 | }, 134 | } 135 | } 136 | 137 | func (r *CiliumInstallResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { 138 | // Prevent panic if the provider has not been configured. 139 | if req.ProviderData == nil { 140 | return 141 | } 142 | 143 | client, ok := req.ProviderData.(*CiliumClient) 144 | 145 | if !ok { 146 | resp.Diagnostics.AddError( 147 | "Unexpected Resource Configure Type", 148 | fmt.Sprintf("Expected *CiliumClient, got: %T. Please report this issue to the provider developers.", req.ProviderData), 149 | ) 150 | 151 | return 152 | } 153 | 154 | r.client = client 155 | } 156 | 157 | func (r *CiliumInstallResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { 158 | var data CiliumInstallResourceModel 159 | c := r.client 160 | if c == nil { 161 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 162 | return 163 | } 164 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 165 | var params = install.Parameters{Writer: os.Stdout} 166 | var options values.Options 167 | 168 | // Read Terraform plan data into the model 169 | resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 170 | 171 | if resp.Diagnostics.HasError() { 172 | return 173 | } 174 | params.Namespace = namespace 175 | params.Version = data.Version.ValueString() 176 | params.HelmReleaseName = helm_release 177 | wait := data.Wait.ValueBool() 178 | 179 | options.Values = ValueList(ctx, data.HelmSet) 180 | 181 | values := data.Values.ValueString() 182 | 183 | if values != "" { 184 | f, err := os.CreateTemp("", ".values.*.yaml") 185 | if err != nil { 186 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create Cilium installer: %s", err)) 187 | } 188 | defer os.Remove(f.Name()) 189 | 190 | if _, err := f.Write([]byte(values)); err != nil { 191 | f.Close() 192 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create Cilium installer: %s", err)) 193 | } 194 | if err := f.Close(); err != nil { 195 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create Cilium installer: %s", err)) 196 | } 197 | options.ValueFiles = []string{f.Name()} 198 | } 199 | 200 | params.HelmOpts = options 201 | 202 | installer, err := install.NewK8sInstaller(k8sClient, params) 203 | if err != nil { 204 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create Cilium installer: %s", err)) 205 | return 206 | } 207 | 208 | if err := installer.InstallWithHelm(context.Background(), k8sClient); err != nil { 209 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to install Cilium: %s", err)) 210 | return 211 | } 212 | 213 | if wait { 214 | if err := c.Wait(); err != nil { 215 | return 216 | } 217 | } 218 | data.Id = types.StringValue(helm_release) 219 | helm_values, err := c.GetHelmValues() 220 | if err != nil { 221 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to install Cilium: %s", err)) 222 | return 223 | } 224 | ca, err := c.GetCA(ctx) 225 | if err != nil { 226 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to retrieve cilium-ca: %s", err)) 227 | return 228 | } 229 | data.CA = types.ObjectValueMust(CaAttributeTypes, ca) 230 | data.HelmValues = types.StringValue(helm_values) 231 | 232 | // Write logs using the tflog package 233 | // Documentation: https://terraform.io/plugin/log 234 | tflog.Trace(ctx, "created a resource") 235 | 236 | // Save data into Terraform state 237 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 238 | } 239 | 240 | func (r *CiliumInstallResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { 241 | var data CiliumInstallResourceModel 242 | c := r.client 243 | if c == nil { 244 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 245 | return 246 | } 247 | 248 | // Read Terraform prior state data into the model 249 | resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 250 | 251 | if resp.Diagnostics.HasError() { 252 | return 253 | } 254 | 255 | _, err := c.GetCurrentRelease() 256 | if err != nil { 257 | resp.State.RemoveResource(ctx) 258 | return 259 | } 260 | helm_values, err := c.GetHelmValues() 261 | if err != nil { 262 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read tfstate: %s", err)) 263 | return 264 | } 265 | version, err := c.GetMetadata() 266 | if err != nil { 267 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read tfstate: %s", err)) 268 | return 269 | } 270 | ca, err := c.GetCA(ctx) 271 | if err != nil { 272 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to retrieve cilium-ca: %s", err)) 273 | return 274 | } 275 | data.CA = types.ObjectValueMust(CaAttributeTypes, ca) 276 | data.HelmValues = types.StringValue(helm_values) 277 | data.Version = types.StringValue(version) 278 | 279 | // Save updated data into Terraform state 280 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 281 | } 282 | 283 | func (r *CiliumInstallResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { 284 | var data CiliumInstallResourceModel 285 | c := r.client 286 | if c == nil { 287 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 288 | return 289 | } 290 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 291 | var params = install.Parameters{Writer: os.Stdout} 292 | var options values.Options 293 | 294 | // Read Terraform plan data into the model 295 | resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 296 | 297 | if resp.Diagnostics.HasError() { 298 | return 299 | } 300 | 301 | params.Namespace = namespace 302 | params.Version = data.Version.ValueString() 303 | params.HelmReleaseName = helm_release 304 | params.HelmResetValues = data.Reset.ValueBool() 305 | params.HelmReuseValues = data.Reuse.ValueBool() 306 | wait := data.Wait.ValueBool() 307 | 308 | options.Values = ValueList(ctx, data.HelmSet) 309 | 310 | values := data.Values.ValueString() 311 | 312 | if values != "" { 313 | f, err := os.CreateTemp("", ".values.*.yaml") 314 | if err != nil { 315 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create Cilium installer: %s", err)) 316 | } 317 | defer os.Remove(f.Name()) 318 | 319 | if _, err := f.Write([]byte(values)); err != nil { 320 | f.Close() 321 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create Cilium installer: %s", err)) 322 | } 323 | if err := f.Close(); err != nil { 324 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to create Cilium installer: %s", err)) 325 | } 326 | options.ValueFiles = []string{f.Name()} 327 | } 328 | params.HelmOpts = options 329 | 330 | installer, err := install.NewK8sInstaller(k8sClient, params) 331 | if err != nil { 332 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to upgrade Cilium: %s", err)) 333 | return 334 | } 335 | if err := installer.UpgradeWithHelm(context.Background(), k8sClient); err != nil { 336 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to upgrade Cilium: %s", err)) 337 | return 338 | } 339 | if wait { 340 | if err := c.Wait(); err != nil { 341 | return 342 | } 343 | } 344 | 345 | helm_values, err := c.GetHelmValues() 346 | if err != nil { 347 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to upgrade Cilium: %s", err)) 348 | return 349 | } 350 | ca, err := c.GetCA(ctx) 351 | if err != nil { 352 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to retrieve cilium-ca: %s", err)) 353 | return 354 | } 355 | data.CA = types.ObjectValueMust(CaAttributeTypes, ca) 356 | data.HelmValues = types.StringValue(helm_values) 357 | // Save updated data into Terraform state 358 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 359 | } 360 | 361 | func (r *CiliumInstallResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { 362 | var data CiliumInstallResourceModel 363 | c := r.client 364 | if c == nil { 365 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 366 | return 367 | } 368 | k8sClient, namespace, helm_release := c.client, c.namespace, c.helm_release 369 | var params = install.UninstallParameters{Writer: os.Stdout} 370 | 371 | // Read Terraform prior state data into the model 372 | resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 373 | 374 | if resp.Diagnostics.HasError() { 375 | return 376 | } 377 | 378 | params.Namespace = namespace 379 | params.HelmReleaseName = helm_release 380 | params.TestNamespace = defaults.ConnectivityCheckNamespace 381 | params.Wait = data.Wait.ValueBool() 382 | 383 | params.Timeout = defaults.UninstallTimeout 384 | ctxb := context.Background() 385 | 386 | uninstaller := install.NewK8sUninstaller(k8sClient, params) 387 | uninstaller.DeleteTestNamespace(ctxb) 388 | 389 | if params.Wait { 390 | fmt.Printf("⌛ Waiting to disable Hubble before uninstalling Cilium\n") 391 | for { 392 | // Wait for the test namespace to be terminated. Subsequent connectivity checks would fail 393 | // if the test namespace is in Terminating state. 394 | _, err := k8sClient.GetNamespace(ctx, params.TestNamespace, metav1.GetOptions{}) 395 | if err == nil { 396 | time.Sleep(defaults.WaitRetryInterval) 397 | } else { 398 | break 399 | } 400 | } 401 | } 402 | if err := uninstaller.UninstallWithHelm(ctxb, k8sClient.HelmActionConfig); err != nil { 403 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("⚠ ️ Unable to uninstall Cilium: %s", err)) 404 | return 405 | } 406 | } 407 | 408 | func (r *CiliumInstallResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { 409 | resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) 410 | } 411 | -------------------------------------------------------------------------------- /cilium/install_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "fmt" 8 | "testing" 9 | 10 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 11 | ) 12 | 13 | func TestAccCiliumInstallResource(t *testing.T) { 14 | resource.Test(t, resource.TestCase{ 15 | PreCheck: func() { testAccPreCheck(t) }, 16 | ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, 17 | Steps: []resource.TestStep{ 18 | // Create and Read testing 19 | { 20 | Config: testAccCiliumInstallResourceConfig("1.15.7"), 21 | Check: resource.ComposeAggregateTestCheckFunc( 22 | resource.TestCheckResourceAttr("cilium.test", "version", "1.15.7"), 23 | resource.TestCheckResourceAttr("cilium.test", "id", "cilium"), 24 | ), 25 | }, 26 | // ImportState testing 27 | { 28 | ResourceName: "cilium.test", 29 | ImportState: true, 30 | ImportStateVerify: true, 31 | ImportStateVerifyIgnore: []string{"data_path", "repository", "reset", "reuse", "values", "wait"}, 32 | }, 33 | // Update and Read testing 34 | { 35 | Config: testAccCiliumInstallResourceConfig("1.15.8"), 36 | Check: resource.ComposeAggregateTestCheckFunc( 37 | resource.TestCheckResourceAttr("cilium.test", "version", "1.15.8"), 38 | resource.TestCheckResourceAttr("cilium.test", "id", "cilium"), 39 | ), 40 | }, 41 | // Delete testing automatically occurs in TestCase 42 | }, 43 | }) 44 | } 45 | 46 | func testAccCiliumInstallResourceConfig(version string) string { 47 | return fmt.Sprintf(` 48 | resource "cilium" "test" { 49 | version = %[1]q 50 | } 51 | `, version) 52 | } 53 | -------------------------------------------------------------------------------- /cilium/kubeproxy_free.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "context" 8 | "fmt" 9 | 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 | ktypes "k8s.io/apimachinery/pkg/types" 12 | 13 | "github.com/hashicorp/terraform-plugin-framework/path" 14 | "github.com/hashicorp/terraform-plugin-framework/resource" 15 | "github.com/hashicorp/terraform-plugin-framework/resource/schema" 16 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" 17 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" 18 | "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" 19 | "github.com/hashicorp/terraform-plugin-framework/types" 20 | "github.com/hashicorp/terraform-plugin-log/tflog" 21 | ) 22 | 23 | // Ensure provider defined types fully satisfy framework interfaces. 24 | var _ resource.Resource = &CiliumKubeProxyDisabledResource{} 25 | var _ resource.ResourceWithImportState = &CiliumKubeProxyDisabledResource{} 26 | 27 | func NewCiliumKubeProxyDisabledResource() resource.Resource { 28 | return &CiliumKubeProxyDisabledResource{} 29 | } 30 | 31 | // CiliumKubeProxyDisabledResource defines the resource implementation. 32 | type CiliumKubeProxyDisabledResource struct { 33 | client *CiliumClient 34 | } 35 | 36 | // CiliumInstallResourceModel describes the resource data model. 37 | type CiliumKubeProxyDisabledResourceModel struct { 38 | Name types.String `tfsdk:"name"` 39 | Namespace types.String `tfsdk:"namespace"` 40 | Id types.String `tfsdk:"id"` 41 | } 42 | 43 | func (r *CiliumKubeProxyDisabledResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { 44 | resp.TypeName = req.ProviderTypeName + "_kubeproxy_free" 45 | } 46 | 47 | func (r *CiliumKubeProxyDisabledResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { 48 | resp.Schema = schema.Schema{ 49 | // This description is used by the documentation generator and the language server. 50 | MarkdownDescription: "Disable Kube-Proxy DaemonSet, equivalent to: `kubectl -n kube-system patch daemonset kube-proxy -p '\"spec\": {\"template\": {\"spec\": {\"nodeSelector\": {\"non-existing\": \"true\"}}}}'`.", 51 | 52 | Attributes: map[string]schema.Attribute{ 53 | "name": schema.StringAttribute{ 54 | MarkdownDescription: ConcatDefault("Name of DaemonSet", "kube-proxy"), 55 | Optional: true, 56 | Computed: true, 57 | Default: stringdefault.StaticString("kube-proxy"), 58 | }, 59 | "namespace": schema.StringAttribute{ 60 | MarkdownDescription: ConcatDefault("Namespace of DaemonSet", "kube-system"), 61 | Optional: true, 62 | Computed: true, 63 | Default: stringdefault.StaticString("kube-system"), 64 | }, 65 | "id": schema.StringAttribute{ 66 | Computed: true, 67 | MarkdownDescription: "kube-proxy free identifier.", 68 | PlanModifiers: []planmodifier.String{ 69 | stringplanmodifier.UseStateForUnknown(), 70 | }, 71 | }, 72 | }, 73 | } 74 | } 75 | 76 | func (r *CiliumKubeProxyDisabledResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { 77 | // Prevent panic if the provider has not been configured. 78 | if req.ProviderData == nil { 79 | return 80 | } 81 | 82 | client, ok := req.ProviderData.(*CiliumClient) 83 | 84 | if !ok { 85 | resp.Diagnostics.AddError( 86 | "Unexpected Resource Configure Type", 87 | fmt.Sprintf("Expected *CiliumClient, got: %T. Please report this issue to the provider developers.", req.ProviderData), 88 | ) 89 | 90 | return 91 | } 92 | 93 | r.client = client 94 | } 95 | 96 | func (r *CiliumKubeProxyDisabledResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { 97 | var data CiliumKubeProxyDisabledResourceModel 98 | c := r.client 99 | if c == nil { 100 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 101 | return 102 | } 103 | k8sClient := c.client 104 | 105 | // Read Terraform plan data into the model 106 | resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 107 | 108 | if resp.Diagnostics.HasError() { 109 | return 110 | } 111 | name := data.Name.ValueString() 112 | namespace := data.Namespace.ValueString() 113 | nodeSelectorKey := "non-existing" 114 | nodeSelectorValue := "true" 115 | patch := []byte(fmt.Sprintf(`{"spec":{"template":{"spec":{"nodeSelector":{"%s":"%s"}}}}}`, nodeSelectorKey, nodeSelectorValue)) 116 | 117 | if err := c.CheckDaemonsetAvailability(ctx, namespace, name); err != nil { 118 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("%s", err)) 119 | } 120 | 121 | if _, err := k8sClient.PatchDaemonSet(ctx, namespace, name, ktypes.StrategicMergePatchType, patch, metav1.PatchOptions{FieldManager: "Terraform"}); err != nil { 122 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("%s", err)) 123 | return 124 | } 125 | 126 | // For the purposes of this example code, hardcoding a response value to 127 | // save into the Terraform state. 128 | data.Id = types.StringValue("cilium-kubeproxy-less") 129 | 130 | // Write logs using the tflog package 131 | // Documentation: https://terraform.io/plugin/log 132 | tflog.Trace(ctx, "created a resource") 133 | 134 | // Save data into Terraform state 135 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 136 | } 137 | 138 | func (r *CiliumKubeProxyDisabledResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { 139 | var data CiliumKubeProxyDisabledResourceModel 140 | c := r.client 141 | if c == nil { 142 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 143 | return 144 | } 145 | 146 | // Read Terraform prior state data into the model 147 | resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 148 | 149 | if resp.Diagnostics.HasError() { 150 | return 151 | } 152 | name := data.Name.ValueString() 153 | namespace := data.Namespace.ValueString() 154 | if err := c.CheckDaemonsetStatus(ctx, namespace, name); err != nil { 155 | resp.State.RemoveResource(ctx) 156 | return 157 | } 158 | 159 | // Save updated data into Terraform state 160 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 161 | } 162 | 163 | func (r *CiliumKubeProxyDisabledResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { 164 | var data CiliumKubeProxyDisabledResourceModel 165 | c := r.client 166 | if c == nil { 167 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 168 | return 169 | } 170 | k8sClient := c.client 171 | 172 | // Read Terraform plan data into the model 173 | resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) 174 | 175 | if resp.Diagnostics.HasError() { 176 | return 177 | } 178 | name := data.Name.ValueString() 179 | namespace := data.Namespace.ValueString() 180 | nodeSelectorKey := "non-existing" 181 | nodeSelectorValue := "true" 182 | patch := []byte(fmt.Sprintf(`{"spec":{"template":{"spec":{"nodeSelector":{"%s":"%s"}}}}}`, nodeSelectorKey, nodeSelectorValue)) 183 | 184 | if err := c.CheckDaemonsetAvailability(ctx, namespace, name); err != nil { 185 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("%s", err)) 186 | } 187 | 188 | if _, err := k8sClient.PatchDaemonSet(ctx, namespace, name, ktypes.StrategicMergePatchType, patch, metav1.PatchOptions{FieldManager: "Terraform"}); err != nil { 189 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("%s", err)) 190 | return 191 | } 192 | 193 | // Save updated data into Terraform state 194 | resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) 195 | } 196 | 197 | func (r *CiliumKubeProxyDisabledResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { 198 | var data CiliumKubeProxyDisabledResourceModel 199 | c := r.client 200 | if c == nil { 201 | resp.Diagnostics.AddError("Client Error", "Unable to connect to kubernetes") 202 | return 203 | } 204 | k8sClient := c.client 205 | 206 | // Read Terraform prior state data into the model 207 | resp.Diagnostics.Append(req.State.Get(ctx, &data)...) 208 | 209 | if resp.Diagnostics.HasError() { 210 | return 211 | } 212 | 213 | name := data.Name.ValueString() 214 | namespace := data.Namespace.ValueString() 215 | nodeSelectorKey := "non-existing" 216 | patch := []byte(fmt.Sprintf(`[{"op":"remove","path":"/spec/template/spec/nodeSelector/%s"}]`, nodeSelectorKey)) 217 | 218 | if err := c.CheckDaemonsetAvailability(ctx, namespace, name); err != nil { 219 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("%s", err)) 220 | } 221 | 222 | if _, err := k8sClient.PatchDaemonSet(ctx, namespace, name, ktypes.JSONPatchType, patch, metav1.PatchOptions{FieldManager: "Terraform"}); err != nil { 223 | resp.Diagnostics.AddError("Client Error", fmt.Sprintf("%s", err)) 224 | return 225 | } 226 | } 227 | 228 | func (r *CiliumKubeProxyDisabledResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { 229 | resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) 230 | } 231 | -------------------------------------------------------------------------------- /cilium/kubeproxy_free_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 10 | ) 11 | 12 | func TestAccCiliumKubeProxyDisabledResource(t *testing.T) { 13 | resource.Test(t, resource.TestCase{ 14 | PreCheck: func() { testAccPreCheck(t) }, 15 | ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, 16 | Steps: []resource.TestStep{ 17 | // Create and Read testing 18 | { 19 | Config: testAccCiliumKubeProxyDisabledResourceConfig(), 20 | Check: resource.ComposeAggregateTestCheckFunc( 21 | resource.TestCheckResourceAttr("cilium_kubeproxy_free.test", "name", "kube-proxy"), 22 | resource.TestCheckResourceAttr("cilium_kubeproxy_free.test", "namespace", "kube-system"), 23 | resource.TestCheckResourceAttr("cilium_kubeproxy_free.test", "id", "cilium-kubeproxy-less"), 24 | ), 25 | }, 26 | // ImportState testing 27 | { 28 | ResourceName: "cilium_kubeproxy_free.test", 29 | ImportState: true, 30 | ImportStateVerify: true, 31 | // This is not normally necessary, but is here because this 32 | // example code does not have an actual upstream service. 33 | // Once the Read method is able to refresh information from 34 | // the upstream service, this can be removed. 35 | ImportStateVerifyIgnore: []string{"name", "namespace"}, 36 | }, 37 | // Update and Read testing 38 | //{ 39 | // Config: testAccCiliumKubeProxyDisabledResourceConfig("two"), 40 | // Check: resource.ComposeAggregateTestCheckFunc( 41 | // resource.TestCheckResourceAttr("cilium_kubeproxy_free.test", "name", "two"), 42 | // ), 43 | //}, 44 | // Delete testing automatically occurs in TestCase 45 | }, 46 | }) 47 | } 48 | 49 | func testAccCiliumKubeProxyDisabledResourceConfig() string { 50 | return ` 51 | resource "cilium_kubeproxy_free" "test" { 52 | } 53 | ` 54 | } 55 | -------------------------------------------------------------------------------- /cilium/provider.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "context" 8 | "encoding/base64" 9 | "fmt" 10 | "os" 11 | 12 | "github.com/cilium/cilium/cilium-cli/k8s" 13 | 14 | "github.com/hashicorp/terraform-plugin-framework/datasource" 15 | "github.com/hashicorp/terraform-plugin-framework/provider" 16 | "github.com/hashicorp/terraform-plugin-framework/provider/schema" 17 | "github.com/hashicorp/terraform-plugin-framework/resource" 18 | "github.com/hashicorp/terraform-plugin-framework/types" 19 | ) 20 | 21 | // Ensure CiliumProvider satisfies various provider interfaces. 22 | var _ provider.Provider = &CiliumProvider{} 23 | 24 | // CiliumProvider defines the provider implementation. 25 | type CiliumProvider struct { 26 | // version is set to the provider version on release, "dev" when the 27 | // provider is built and ran locally, and "test" when running acceptance 28 | // testing. 29 | version string 30 | } 31 | 32 | // CiliumProviderModel describes the provider data model. 33 | type CiliumProviderModel struct { 34 | Context types.String `tfsdk:"context"` 35 | ConfigPath types.String `tfsdk:"config_path"` 36 | ConfigContent types.String `tfsdk:"config_content"` 37 | Namespace types.String `tfsdk:"namespace"` 38 | HelmRelease types.String `tfsdk:"helm_release"` 39 | } 40 | 41 | func (p *CiliumProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) { 42 | resp.TypeName = "cilium" 43 | resp.Version = p.version 44 | } 45 | 46 | func (p *CiliumProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) { 47 | resp.Schema = schema.Schema{ 48 | Attributes: map[string]schema.Attribute{ 49 | "context": schema.StringAttribute{ 50 | MarkdownDescription: ConcatDefault("Context of kubeconfig file", "default context"), 51 | Optional: true, 52 | }, 53 | "config_path": schema.StringAttribute{ 54 | MarkdownDescription: ConcatDefault("A path to a kube config file", "~/.kube/config"), 55 | Optional: true, 56 | }, 57 | "config_content": schema.StringAttribute{ 58 | MarkdownDescription: ConcatDefault("The content of kube config file", ""), 59 | Optional: true, 60 | }, 61 | "namespace": schema.StringAttribute{ 62 | MarkdownDescription: ConcatDefault("Namespace to install cilium", "kube-system"), 63 | Optional: true, 64 | }, 65 | "helm_release": schema.StringAttribute{ 66 | MarkdownDescription: ConcatDefault("Helm Release to install cilium", "cilium"), 67 | Optional: true, 68 | }, 69 | }, 70 | } 71 | } 72 | 73 | func (p *CiliumProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { 74 | var data CiliumProviderModel 75 | 76 | resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) 77 | 78 | if resp.Diagnostics.HasError() { 79 | return 80 | } 81 | 82 | namespace := data.Namespace.ValueString() 83 | config_path := data.ConfigPath.ValueString() 84 | context := data.Context.ValueString() 85 | helm_release := data.HelmRelease.ValueString() 86 | config_content := data.ConfigContent.ValueString() 87 | 88 | if helm_release == "" { 89 | helm_release = "cilium" 90 | } 91 | if namespace == "" { 92 | namespace = "kube-system" 93 | } 94 | if config_content != "" { 95 | config_content_str, err := base64.StdEncoding.DecodeString(config_content) 96 | if err != nil { 97 | panic(err) 98 | } 99 | f, err := os.CreateTemp("", "kubeconfig") 100 | if err != nil { 101 | panic(err) 102 | } 103 | if _, err := f.Write(config_content_str); err != nil { 104 | panic(err) 105 | } 106 | if err := f.Close(); err != nil { 107 | panic(err) 108 | } 109 | config_path = f.Name() 110 | } 111 | if config_path != "" { 112 | os.Setenv("KUBECONFIG", config_path) 113 | } 114 | 115 | impersonate_as := "" 116 | impersonate_groups := []string{} 117 | 118 | client, err := k8s.NewClient(context, config_path, namespace, impersonate_as, impersonate_groups) 119 | if err != nil { 120 | fmt.Printf("unable to create Kubernetes client: %v\n", err) 121 | return 122 | } 123 | 124 | // Configuration values are now available. 125 | // if data.Endpoint.IsNull() { /* ... */ } 126 | 127 | // Example client configuration for data sources and resources 128 | resp.DataSourceData = &CiliumClient{client: client, namespace: namespace, helm_release: helm_release} 129 | resp.ResourceData = &CiliumClient{client: client, namespace: namespace, helm_release: helm_release} 130 | } 131 | 132 | func (p *CiliumProvider) Resources(ctx context.Context) []func() resource.Resource { 133 | return []func() resource.Resource{ 134 | NewCiliumInstallResource, 135 | NewCiliumConfigResource, 136 | NewCiliumClusterMeshEnableResource, 137 | NewCiliumClusterMeshConnectResource, 138 | NewCiliumHubbleResource, 139 | NewCiliumKubeProxyDisabledResource, 140 | } 141 | } 142 | 143 | func (p *CiliumProvider) DataSources(ctx context.Context) []func() datasource.DataSource { 144 | return []func() datasource.DataSource{ 145 | NewCiliumHelmValuesDataSource, 146 | } 147 | } 148 | 149 | func New(version string) func() provider.Provider { 150 | return func() provider.Provider { 151 | return &CiliumProvider{ 152 | version: version, 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /cilium/provider_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/hashicorp/terraform-plugin-framework/providerserver" 10 | "github.com/hashicorp/terraform-plugin-go/tfprotov6" 11 | ) 12 | 13 | // testAccProtoV6ProviderFactories are used to instantiate a provider during 14 | // acceptance testing. The factory function will be invoked for every Terraform 15 | // CLI command executed to create a provider server to which the CLI can 16 | // reattach. 17 | var testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){ 18 | "cilium": providerserver.NewProtocol6WithError(New("test")()), 19 | } 20 | 21 | func testAccPreCheck(t *testing.T) { 22 | // You can add code here to run prior to any test case execution, for example assertions 23 | // about the appropriate environment variables being set are common to see in a pre-check 24 | // function. 25 | } 26 | -------------------------------------------------------------------------------- /docs/data-sources/helm_values.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium_helm_values Data Source - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Helm values of cilium 7 | --- 8 | 9 | # cilium_helm_values (Data Source) 10 | 11 | Helm values of cilium 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | data "cilium_helm_values" "example" {} 17 | 18 | resource "local_file" "example" { 19 | content = data.cilium_helm_values.example.yaml 20 | filename = "${path.module}/values.yaml" 21 | } 22 | ``` 23 | 24 | 25 | 26 | ## Schema 27 | 28 | ### Read-Only 29 | 30 | - `yaml` (String) Yaml output 31 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium Provider" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # cilium Provider 10 | 11 | ## Example Usage 12 | 13 | ```terraform 14 | provider "cilium" { 15 | config_path = "${path.module}/kubeconfig" 16 | } 17 | ``` 18 | 19 | * More examples: 20 | * https://github.com/orgs/tf-cilium/repositories 21 | 22 | 23 | 24 | ## Schema 25 | 26 | ### Optional 27 | 28 | - `config_path` (String) A path to a kube config file (Default: `~/.kube/config`). 29 | - `config_content` (String) kube config content in base 64, override config_path if define. 30 | - `context` (String) Context of kubeconfig file (Default: `default context`). 31 | - `namespace` (String) Namespace to install cilium (Default: `kube-system`). 32 | - `helm_release` (String) Helm release of cilium installation (Default: `cilium`). 33 | -------------------------------------------------------------------------------- /docs/resources/cilium.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium Resource - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Install resource for Cilium. This is equivalent to cilium cli: cilium install, cilium upgrade and cilium uninstall: It manages cilium helm chart 7 | --- 8 | 9 | # cilium (Resource) 10 | 11 | Install resource for Cilium. This is equivalent to cilium cli: `cilium install`, `cilium upgrade` and `cilium uninstall`: It manages cilium helm chart 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | resource "kind_cluster" "example" { 17 | name = "test-cluster" 18 | 19 | kind_config { 20 | kind = "Cluster" 21 | api_version = "kind.x-k8s.io/v1alpha4" 22 | 23 | node { 24 | role = "control-plane" 25 | } 26 | 27 | node { 28 | role = "worker" 29 | } 30 | 31 | networking { 32 | disable_default_cni = true 33 | } 34 | } 35 | } 36 | 37 | resource "cilium" "example" { 38 | set = [ 39 | "ipam.mode=kubernetes", 40 | "ipam.operator.replicas=1", 41 | "tunnel=vxlan", 42 | ] 43 | version = "1.14.5" 44 | } 45 | ``` 46 | 47 | * More examples: 48 | * AWS: https://github.com/tf-cilium/terraform-eks-cilium 49 | * Azure: https://github.com/tf-cilium/terraform-aks-cilium 50 | * GCP: https://github.com/tf-cilium/terraform-gke-cilium 51 | * Kind: https://github.com/tf-cilium/terraform-kind-cilium 52 | 53 | 54 | 55 | ## Schema 56 | 57 | ### Optional 58 | 59 | - `data_path` (String) Datapath mode to use { tunnel | native | aws-eni | gke | azure | aks-byocni } (Default: `autodetected`). 60 | - `repository` (String) Helm chart repository to download Cilium charts from (Default: `https://helm.cilium.io`). 61 | - `reset` (Boolean) When upgrading, reset the helm values to the ones built into the chart (Default: `false`). 62 | - `reuse` (Boolean) When upgrading, reuse the helm values from the latest release unless any overrides from are set from other flags. This option takes precedence over HelmResetValues (Default: `true`). 63 | - `set` (List of String) Set helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2 (Default: `[]`). 64 | - `values` (String) values in raw yaml to pass to helm. (Default: `empty`). 65 | - `version` (String) Version of Cilium (Default: `v1.14.5`). 66 | - `wait` (Boolean) Wait for Cilium status is ok (Default: `true`). 67 | 68 | ### Read-Only 69 | 70 | - `id` (String) Cilium install identifier 71 | - `helm_values` (String) Helm values (`helm get values -n kube-system cilium`) 72 | - `ca` (Object, sensitive) Cilium certificates value, Format: `{crt: "b64...", key: "b64.."}` (Equivalent to `kubectl get secret cilium-ca -n kube-system -o yaml`) 73 | -------------------------------------------------------------------------------- /docs/resources/clustermesh.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium_clustermesh Resource - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Cluster Mesh resource. This is equivalent to cilium cli: cilium clustermesh enable and cilium clustermesh disable: It manages the activation of Cluster Mesh on one Kubernetes cluster. 7 | --- 8 | 9 | # cilium_clustermesh (Resource) 10 | 11 | Cluster Mesh resource. This is equivalent to cilium cli: `cilium clustermesh enable` and `cilium clustermesh disable`: It manages the activation of Cluster Mesh on one Kubernetes cluster. 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | resource "cilium" "example" { 17 | set = [ 18 | "cluster.name=clustermesh1", 19 | "cluster.id=1", 20 | "ipam.mode=kubernetes", 21 | ] 22 | version = "1.14.5" 23 | } 24 | 25 | resource "cilium_clustermesh" "example" { 26 | service_type = "LoadBalancer" 27 | depends_on = [ 28 | cilium.example 29 | ] 30 | } 31 | ``` 32 | 33 | * More examples: 34 | * https://github.com/tf-cilium/terraform-kind-cilium-clustermesh 35 | * https://github.com/littlejo/terraform-provider-cilium/tree/main/.github/tf/clustermesh 36 | 37 | 38 | 39 | ## Schema 40 | 41 | ### Optional 42 | 43 | - `enable_external_workloads` (Boolean) Enable support for external workloads, such as VMs (Default: `false`). 44 | - `enable_kv_store_mesh` (Boolean) Enable kvstoremesh, an extension which caches remote cluster information in the local kvstore (Cilium >=1.14 only) (Default: `false`). 45 | - `service_type` (String) Type of Kubernetes service to expose control plane { LoadBalancer | NodePort | ClusterIP } (Default: `autodetected`). 46 | - `wait` (Boolean) Wait Cluster Mesh status is ok (Default: `true`). 47 | 48 | ### Read-Only 49 | 50 | - `id` (String) Cilium ClusterMesh identifier 51 | -------------------------------------------------------------------------------- /docs/resources/clustermesh_connection.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium_clustermesh_connection Resource - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Cluster Mesh connection resource. This is equivalent to cilium cli: cilium clustermesh connect and cilium clustermesh disconnect: It manages the connections between two Kubernetes clusters. 7 | --- 8 | 9 | # cilium_clustermesh_connection (Resource) 10 | 11 | Cluster Mesh connection resource. This is equivalent to cilium cli: `cilium clustermesh connect` and `cilium clustermesh disconnect`: It manages the connections between two Kubernetes clusters. 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | resource "cilium_clustermesh_connection" "example" { 17 | destination_contexts = ["context-2"] 18 | } 19 | 20 | provider "cilium" { 21 | config_path = "${path.module}/kubeconfig" 22 | context = "context-1" 23 | } 24 | ``` 25 | 26 | * More examples: 27 | * https://github.com/tf-cilium/terraform-kind-cilium-clustermesh 28 | * https://github.com/littlejo/terraform-provider-cilium/tree/main/.github/tf/clustermesh 29 | 30 | 31 | 32 | ## Schema 33 | 34 | ### Optional 35 | 36 | - `destination_contexts` (List of String) Kubernetes configuration contexts of destination clusters 37 | - `connection_mode` (String) Connection Mode { `unicast` | `bidirectional` | `mesh` } (Default: `bidirectional`). 38 | - `parallel` (Number) Number of parallel connections of destination clusters (Default: `1`). 39 | 40 | ### Read-Only 41 | 42 | - `id` (String) Cilium ClusterMesh Connection identifier 43 | -------------------------------------------------------------------------------- /docs/resources/config.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium_config Resource - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Config resource for Cilium. This is equivalent to cilium cli: cilium config: It manages the cilium Kubernetes ConfigMap resource 7 | --- 8 | 9 | # cilium_config (Resource) 10 | 11 | Config resource for Cilium. This is equivalent to cilium cli: `cilium config`: It manages the cilium Kubernetes ConfigMap resource 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | resource "cilium_config" "example" { 17 | key = "debug" 18 | value = "true" 19 | } 20 | ``` 21 | 22 | 23 | 24 | ## Schema 25 | 26 | ### Required 27 | 28 | - `key` (String) Key of the config 29 | - `value` (String) Value of the key 30 | 31 | ### Optional 32 | 33 | - `restart` (Boolean) Restart Cilium pods (Default: `true`). 34 | 35 | ### Read-Only 36 | 37 | - `id` (String) Cilium config identifier 38 | -------------------------------------------------------------------------------- /docs/resources/hubble.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium_hubble Resource - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Hubble resource for Cilium. This is equivalent to cilium cli: cilium hubble: It manages cilium hubble 7 | --- 8 | 9 | # cilium_hubble (Resource) 10 | 11 | Hubble resource for Cilium. This is equivalent to cilium cli: `cilium hubble`: It manages cilium hubble 12 | 13 | ## Example Usage 14 | 15 | ```terraform 16 | resource "cilium_hubble" "example" { 17 | ui = true 18 | } 19 | ``` 20 | 21 | 22 | 23 | ## Schema 24 | 25 | ### Optional 26 | 27 | - `relay` (Boolean) Deploy Hubble Relay (Default: `true`). 28 | - `ui` (Boolean) Enable Hubble UI (Default: `false`). 29 | 30 | ### Read-Only 31 | 32 | - `id` (String) Cilium hubble identifier 33 | -------------------------------------------------------------------------------- /docs/resources/kubeproxy_free.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium_kubeproxy_free Resource - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Disable Kube-Proxy DaemonSet, equivalent to: kubectl -n kube-system patch daemonset kube-proxy -p '"spec": {"template": {"spec": {"nodeSelector": {"non-existing": "true"}}}}'. 7 | --- 8 | 9 | # cilium_kubeproxy_free (Resource) 10 | 11 | Disable Kube-Proxy DaemonSet, equivalent to: `kubectl -n kube-system patch daemonset kube-proxy -p '"spec": {"template": {"spec": {"nodeSelector": {"non-existing": "true"}}}}'`. 12 | 13 | 14 | 15 | ## Schema 16 | 17 | ### Optional 18 | 19 | - `name` (String) Name of DaemonSet (Default: `kube-proxy`). 20 | - `namespace` (String) Namespace in which to install (Default: `kube-system`). 21 | 22 | ### Read-Only 23 | 24 | - `id` (String) kube-proxy free identifier. 25 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | This directory contains examples that are mostly used for documentation, but can also be run/tested manually via the Terraform CLI. 4 | 5 | The document generation tool looks for files in the following locations by default. All other *.tf files besides the ones mentioned below are ignored by the documentation tool. This is useful for creating examples that can run and/or ar testable even if some parts are not relevant for the documentation. 6 | 7 | * **provider/provider.tf** example file for the provider index page 8 | * **data-sources/`full data source name`/data-source.tf** example file for the named data source page 9 | * **resources/`full resource name`/resource.tf** example file for the named data source page 10 | -------------------------------------------------------------------------------- /examples/data-sources/helm_values/example_1.tf: -------------------------------------------------------------------------------- 1 | data "cilium_helm_values" "example" {} 2 | 3 | resource "local_file" "example" { 4 | content = data.cilium_helm_values.example.yaml 5 | filename = "${path.module}/values.yaml" 6 | } 7 | -------------------------------------------------------------------------------- /examples/provider/provider.tf: -------------------------------------------------------------------------------- 1 | provider "cilium" { 2 | config_path = "${path.module}/kubeconfig" 3 | } 4 | -------------------------------------------------------------------------------- /examples/resources/cilium/example_1.tf: -------------------------------------------------------------------------------- 1 | resource "kind_cluster" "example" { 2 | name = "test-cluster" 3 | 4 | kind_config { 5 | kind = "Cluster" 6 | api_version = "kind.x-k8s.io/v1alpha4" 7 | 8 | node { 9 | role = "control-plane" 10 | } 11 | 12 | node { 13 | role = "worker" 14 | } 15 | 16 | networking { 17 | disable_default_cni = true 18 | } 19 | } 20 | } 21 | 22 | resource "cilium" "example" { 23 | set = [ 24 | "ipam.mode=kubernetes", 25 | "ipam.operator.replicas=1", 26 | "tunnel=vxlan", 27 | ] 28 | version = "1.14.5" 29 | } 30 | -------------------------------------------------------------------------------- /examples/resources/clustermesh/example_1.tf: -------------------------------------------------------------------------------- 1 | resource "cilium" "example" { 2 | set = [ 3 | "cluster.name=clustermesh1", 4 | "cluster.id=1", 5 | "ipam.mode=kubernetes", 6 | ] 7 | version = "1.14.5" 8 | } 9 | 10 | resource "cilium_clustermesh" "example" { 11 | service_type = "LoadBalancer" 12 | depends_on = [ 13 | cilium.example 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /examples/resources/clustermesh_connection/example_1.tf: -------------------------------------------------------------------------------- 1 | resource "cilium_clustermesh_connection" "example" { 2 | destination_contexts = ["context-2"] 3 | } 4 | 5 | provider "cilium" { 6 | config_path = "${path.module}/kubeconfig" 7 | context = "context-1" 8 | } 9 | -------------------------------------------------------------------------------- /examples/resources/config/example_1.tf: -------------------------------------------------------------------------------- 1 | resource "cilium_config" "example" { 2 | key = "debug" 3 | value = "true" 4 | } 5 | -------------------------------------------------------------------------------- /examples/resources/hubble/example_1.tf: -------------------------------------------------------------------------------- 1 | resource "cilium_hubble" "example" { 2 | ui = true 3 | } 4 | -------------------------------------------------------------------------------- /examples/resources/kubeproxy_free/example_1.tf: -------------------------------------------------------------------------------- 1 | resource "kind_cluster" "example" { 2 | name = "test-cluster" 3 | 4 | kind_config { 5 | kind = "Cluster" 6 | api_version = "kind.x-k8s.io/v1alpha4" 7 | 8 | node { 9 | role = "control-plane" 10 | } 11 | 12 | node { 13 | role = "worker" 14 | } 15 | 16 | networking { 17 | disable_default_cni = true 18 | } 19 | } 20 | } 21 | 22 | resource "cilium" "example" { 23 | set = [ 24 | "ipam.mode=kubernetes", 25 | "ipam.operator.replicas=1", 26 | "tunnel=vxlan", 27 | ] 28 | version = "1.14.5" 29 | } 30 | 31 | #Complete example: https://github.com/littlejo/terraform-kind-cilium 32 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/littlejo/terraform-provider-cilium 2 | 3 | go 1.24.0 4 | 5 | toolchain go1.24.3 6 | 7 | require ( 8 | github.com/cilium/cilium v1.18.0-pre.2 9 | github.com/hashicorp/terraform-plugin-docs v0.21.0 10 | github.com/hashicorp/terraform-plugin-framework v1.15.0 11 | github.com/hashicorp/terraform-plugin-go v0.27.0 12 | github.com/hashicorp/terraform-plugin-log v0.9.0 13 | github.com/hashicorp/terraform-plugin-testing v1.13.1 14 | gopkg.in/yaml.v3 v3.0.1 15 | helm.sh/helm/v3 v3.18.0 16 | k8s.io/apimachinery v0.33.1 17 | ) 18 | 19 | require ( 20 | dario.cat/mergo v1.0.1 // indirect 21 | github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect 22 | github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect 23 | github.com/BurntSushi/toml v1.5.0 // indirect 24 | github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect 25 | github.com/MakeNowJust/heredoc v1.0.0 // indirect 26 | github.com/Masterminds/goutils v1.1.1 // indirect 27 | github.com/Masterminds/semver/v3 v3.3.0 // indirect 28 | github.com/Masterminds/sprig/v3 v3.3.0 // indirect 29 | github.com/Masterminds/squirrel v1.5.4 // indirect 30 | github.com/ProtonMail/go-crypto v1.1.6 // indirect 31 | github.com/agext/levenshtein v1.2.2 // indirect 32 | github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect 33 | github.com/armon/go-radix v1.0.0 // indirect 34 | github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect 35 | github.com/beorn7/perks v1.0.1 // indirect 36 | github.com/bgentry/speakeasy v0.1.0 // indirect 37 | github.com/blang/semver/v4 v4.0.0 // indirect 38 | github.com/bmatcuk/doublestar/v4 v4.8.1 // indirect 39 | github.com/cespare/xxhash/v2 v2.3.0 // indirect 40 | github.com/chai2010/gettext-go v1.0.2 // indirect 41 | github.com/cilium/charts v0.0.0-20250321182823-dd713bc54e89 // indirect 42 | github.com/cilium/ebpf v0.18.0 // indirect 43 | github.com/cilium/hive v0.0.0-20250328192914-7f3c86c9c25e // indirect 44 | github.com/cilium/proxy v0.0.0-20250410004025-67b7ec895b08 // indirect 45 | github.com/cilium/statedb v0.3.7 // indirect 46 | github.com/cilium/stream v0.0.1 // indirect 47 | github.com/cilium/workerpool v1.3.0 // indirect 48 | github.com/cloudflare/circl v1.6.0 // indirect 49 | github.com/containerd/containerd v1.7.27 // indirect 50 | github.com/containerd/errdefs v0.3.0 // indirect 51 | github.com/containerd/log v0.1.0 // indirect 52 | github.com/containerd/platforms v0.2.1 // indirect 53 | github.com/cyphar/filepath-securejoin v0.4.1 // indirect 54 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect 55 | github.com/distribution/reference v0.6.0 // indirect 56 | github.com/docker/cli v25.0.1+incompatible // indirect 57 | github.com/docker/distribution v2.8.3+incompatible // indirect 58 | github.com/docker/docker v28.0.4+incompatible // indirect 59 | github.com/docker/docker-credential-helpers v0.8.2 // indirect 60 | github.com/docker/go-connections v0.5.0 // indirect 61 | github.com/docker/go-metrics v0.0.1 // indirect 62 | github.com/emicklei/go-restful/v3 v3.12.0 // indirect 63 | github.com/evanphx/json-patch v5.9.11+incompatible // indirect 64 | github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect 65 | github.com/fatih/color v1.18.0 // indirect 66 | github.com/felixge/httpsnoop v1.0.4 // indirect 67 | github.com/fsnotify/fsnotify v1.9.0 // indirect 68 | github.com/fxamacker/cbor/v2 v2.7.0 // indirect 69 | github.com/go-errors/errors v1.4.2 // indirect 70 | github.com/go-gorp/gorp/v3 v3.1.0 // indirect 71 | github.com/go-logr/logr v1.4.2 // indirect 72 | github.com/go-logr/stdr v1.2.2 // indirect 73 | github.com/go-openapi/analysis v0.23.0 // indirect 74 | github.com/go-openapi/errors v0.22.1 // indirect 75 | github.com/go-openapi/jsonpointer v0.21.0 // indirect 76 | github.com/go-openapi/jsonreference v0.21.0 // indirect 77 | github.com/go-openapi/loads v0.22.0 // indirect 78 | github.com/go-openapi/runtime v0.28.0 // indirect 79 | github.com/go-openapi/spec v0.21.0 // indirect 80 | github.com/go-openapi/strfmt v0.23.0 // indirect 81 | github.com/go-openapi/swag v0.23.1 // indirect 82 | github.com/go-openapi/validate v0.24.0 // indirect 83 | github.com/go-viper/mapstructure/v2 v2.2.1 // indirect 84 | github.com/gobwas/glob v0.2.3 // indirect 85 | github.com/gogo/protobuf v1.3.2 // indirect 86 | github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect 87 | github.com/golang/protobuf v1.5.4 // indirect 88 | github.com/google/btree v1.1.3 // indirect 89 | github.com/google/gnostic-models v0.6.9 // indirect 90 | github.com/google/go-cmp v0.7.0 // indirect 91 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect 92 | github.com/google/uuid v1.6.0 // indirect 93 | github.com/gopacket/gopacket v1.3.1 // indirect 94 | github.com/gorilla/mux v1.8.1 // indirect 95 | github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect 96 | github.com/gosuri/uitable v0.0.4 // indirect 97 | github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect 98 | github.com/hashicorp/cli v1.1.7 // indirect 99 | github.com/hashicorp/errwrap v1.1.0 // indirect 100 | github.com/hashicorp/go-checkpoint v0.5.0 // indirect 101 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect 102 | github.com/hashicorp/go-cty v1.5.0 // indirect 103 | github.com/hashicorp/go-hclog v1.6.3 // indirect 104 | github.com/hashicorp/go-multierror v1.1.1 // indirect 105 | github.com/hashicorp/go-plugin v1.6.3 // indirect 106 | github.com/hashicorp/go-retryablehttp v0.7.7 // indirect 107 | github.com/hashicorp/go-uuid v1.0.3 // indirect 108 | github.com/hashicorp/go-version v1.7.0 // indirect 109 | github.com/hashicorp/hc-install v0.9.2 // indirect 110 | github.com/hashicorp/hcl/v2 v2.23.0 // indirect 111 | github.com/hashicorp/logutils v1.0.0 // indirect 112 | github.com/hashicorp/terraform-exec v0.23.0 // indirect 113 | github.com/hashicorp/terraform-json v0.25.0 // indirect 114 | github.com/hashicorp/terraform-plugin-sdk/v2 v2.37.0 // indirect 115 | github.com/hashicorp/terraform-registry-address v0.2.5 // indirect 116 | github.com/hashicorp/terraform-svchost v0.1.1 // indirect 117 | github.com/hashicorp/yamux v0.1.1 // indirect 118 | github.com/huandu/xstrings v1.5.0 // indirect 119 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 120 | github.com/jhump/protoreflect v1.15.3 // indirect 121 | github.com/jmoiron/sqlx v1.4.0 // indirect 122 | github.com/josharian/intern v1.0.0 // indirect 123 | github.com/json-iterator/go v1.1.12 // indirect 124 | github.com/klauspost/compress v1.18.0 // indirect 125 | github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect 126 | github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect 127 | github.com/lib/pq v1.10.9 // indirect 128 | github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect 129 | github.com/mackerelio/go-osstat v0.2.5 // indirect 130 | github.com/mailru/easyjson v0.9.0 // indirect 131 | github.com/mattn/go-colorable v0.1.14 // indirect 132 | github.com/mattn/go-isatty v0.0.20 // indirect 133 | github.com/mattn/go-runewidth v0.0.13 // indirect 134 | github.com/mitchellh/copystructure v1.2.0 // indirect 135 | github.com/mitchellh/go-testing-interface v1.14.1 // indirect 136 | github.com/mitchellh/go-wordwrap v1.0.1 // indirect 137 | github.com/mitchellh/mapstructure v1.5.0 // indirect 138 | github.com/mitchellh/reflectwalk v1.0.2 // indirect 139 | github.com/moby/locker v1.0.1 // indirect 140 | github.com/moby/spdystream v0.5.0 // indirect 141 | github.com/moby/term v0.5.2 // indirect 142 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 143 | github.com/modern-go/reflect2 v1.0.2 // indirect 144 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect 145 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 146 | github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect 147 | github.com/oklog/run v1.0.0 // indirect 148 | github.com/oklog/ulid v1.3.1 // indirect 149 | github.com/onsi/ginkgo/v2 v2.22.0 // indirect 150 | github.com/opencontainers/go-digest v1.0.0 // indirect 151 | github.com/opencontainers/image-spec v1.1.1 // indirect 152 | github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect 153 | github.com/pelletier/go-toml/v2 v2.2.3 // indirect 154 | github.com/peterbourgon/diskv v2.0.1+incompatible // indirect 155 | github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect 156 | github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect 157 | github.com/pkg/errors v0.9.1 // indirect 158 | github.com/posener/complete v1.2.3 // indirect 159 | github.com/prometheus/client_golang v1.22.0 // indirect 160 | github.com/prometheus/client_model v0.6.1 // indirect 161 | github.com/prometheus/common v0.63.0 // indirect 162 | github.com/prometheus/procfs v0.16.0 // indirect 163 | github.com/rivo/uniseg v0.4.4 // indirect 164 | github.com/rubenv/sql-migrate v1.8.0 // indirect 165 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 166 | github.com/sagikazarmark/locafero v0.7.0 // indirect 167 | github.com/sasha-s/go-deadlock v0.3.5 // indirect 168 | github.com/shopspring/decimal v1.4.0 // indirect 169 | github.com/sirupsen/logrus v1.9.3 // indirect 170 | github.com/sourcegraph/conc v0.3.0 // indirect 171 | github.com/spf13/afero v1.14.0 // indirect 172 | github.com/spf13/cast v1.7.1 // indirect 173 | github.com/spf13/cobra v1.9.1 // indirect 174 | github.com/spf13/pflag v1.0.6 // indirect 175 | github.com/spf13/viper v1.20.1 // indirect 176 | github.com/subosito/gotenv v1.6.0 // indirect 177 | github.com/vishvananda/netlink v1.3.1-0.20250425193846-9d88d8385bf9 // indirect 178 | github.com/vishvananda/netns v0.0.5 // indirect 179 | github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect 180 | github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect 181 | github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect 182 | github.com/x448/float16 v0.8.4 // indirect 183 | github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect 184 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect 185 | github.com/xeipuuv/gojsonschema v1.2.0 // indirect 186 | github.com/xlab/treeprint v1.2.0 // indirect 187 | github.com/yuin/goldmark v1.7.7 // indirect 188 | github.com/yuin/goldmark-meta v1.1.0 // indirect 189 | github.com/zclconf/go-cty v1.16.2 // indirect 190 | go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect 191 | go.mongodb.org/mongo-driver v1.14.0 // indirect 192 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect 193 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect 194 | go.opentelemetry.io/otel v1.35.0 // indirect 195 | go.opentelemetry.io/otel/metric v1.35.0 // indirect 196 | go.opentelemetry.io/otel/trace v1.35.0 // indirect 197 | go.uber.org/dig v1.17.1 // indirect 198 | go.uber.org/multierr v1.11.0 // indirect 199 | go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect 200 | golang.org/x/crypto v0.38.0 // indirect 201 | golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect 202 | golang.org/x/mod v0.24.0 // indirect 203 | golang.org/x/net v0.39.0 // indirect 204 | golang.org/x/oauth2 v0.29.0 // indirect 205 | golang.org/x/sync v0.14.0 // indirect 206 | golang.org/x/sys v0.33.0 // indirect 207 | golang.org/x/term v0.32.0 // indirect 208 | golang.org/x/text v0.25.0 // indirect 209 | golang.org/x/time v0.11.0 // indirect 210 | golang.org/x/tools v0.32.0 // indirect 211 | google.golang.org/appengine v1.6.8 // indirect 212 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect 213 | google.golang.org/grpc v1.72.1 // indirect 214 | google.golang.org/protobuf v1.36.6 // indirect 215 | gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect 216 | gopkg.in/inf.v0 v0.9.1 // indirect 217 | gopkg.in/yaml.v2 v2.4.0 // indirect 218 | k8s.io/api v0.33.0 // indirect 219 | k8s.io/apiextensions-apiserver v0.33.0 // indirect 220 | k8s.io/apiserver v0.33.0 // indirect 221 | k8s.io/cli-runtime v0.33.0 // indirect 222 | k8s.io/client-go v0.33.0 // indirect 223 | k8s.io/component-base v0.33.0 // indirect 224 | k8s.io/klog/v2 v2.130.1 // indirect 225 | k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect 226 | k8s.io/kubectl v0.33.0 // indirect 227 | k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e // indirect 228 | oras.land/oras-go v1.2.5 // indirect 229 | oras.land/oras-go/v2 v2.5.0 // indirect 230 | sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect 231 | sigs.k8s.io/kustomize/api v0.19.0 // indirect 232 | sigs.k8s.io/kustomize/kyaml v0.19.0 // indirect 233 | sigs.k8s.io/randfill v1.0.0 // indirect 234 | sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect 235 | sigs.k8s.io/yaml v1.4.0 // indirect 236 | ) 237 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package main 5 | 6 | import ( 7 | "context" 8 | "flag" 9 | "log" 10 | 11 | "github.com/hashicorp/terraform-plugin-framework/providerserver" 12 | "github.com/littlejo/terraform-provider-cilium/cilium" 13 | ) 14 | 15 | // Run "go generate" to format example terraform files and generate the docs for the registry/website 16 | 17 | // If you do not have terraform installed, you can remove the formatting command, but its suggested to 18 | // ensure the documentation is formatted properly. 19 | //go:generate terraform fmt -recursive ./examples/ 20 | 21 | // Run the docs generation tool, check its repository for more information on how it works and how docs 22 | // can be customized. 23 | //go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs 24 | 25 | var ( 26 | // these will be set by the goreleaser configuration 27 | // to appropriate values for the compiled binary. 28 | version string = "dev" 29 | 30 | // goreleaser can pass other information to the main package, such as the specific commit 31 | // https://goreleaser.com/cookbooks/using-main.version/ 32 | ) 33 | 34 | func main() { 35 | var debug bool 36 | 37 | flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve") 38 | flag.Parse() 39 | 40 | opts := providerserver.ServeOpts{ 41 | // TODO: Update this string with the published name of your provider. 42 | Address: "registry.terraform.io/littlejo/cilium", 43 | Debug: debug, 44 | } 45 | 46 | err := providerserver.Serve(context.Background(), provider.New(version), opts) 47 | 48 | if err != nil { 49 | log.Fatal(err.Error()) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base" 5 | ], 6 | "packageRules": [ 7 | { 8 | "managers": ["terraform"], 9 | "matchPackageNames": ["cilium"], 10 | "registryUrls": [ 11 | "https://github.com/cilium/cilium" 12 | ], 13 | "versioning": "semver" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /templates/data-sources/helm_values.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium_helm_values Data Source - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Helm values of cilium 7 | --- 8 | 9 | {{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. 10 | 11 | For example, the {{ SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} 12 | 13 | # cilium_helm_values (Data Source) 14 | 15 | Helm values of cilium 16 | 17 | ## Example Usage 18 | 19 | {{tffile "examples/data-sources/helm_values/example_1.tf"}} 20 | 21 | 22 | 23 | ## Schema 24 | 25 | ### Read-Only 26 | 27 | - `yaml` (String) Yaml output 28 | -------------------------------------------------------------------------------- /templates/index.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium Provider" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | {{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. 10 | 11 | For example, the {{ SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} 12 | 13 | # cilium Provider 14 | 15 | ## Example Usage 16 | 17 | {{tffile "examples/provider/provider.tf"}} 18 | 19 | * More examples: 20 | * https://github.com/orgs/tf-cilium/repositories 21 | 22 | 23 | 24 | ## Schema 25 | 26 | ### Optional 27 | 28 | - `config_path` (String) A path to a kube config file (Default: `~/.kube/config`). 29 | - `config_content` (String) kube config content in base 64, override config_path if define. 30 | - `context` (String) Context of kubeconfig file (Default: `default context`). 31 | - `namespace` (String) Namespace to install cilium (Default: `kube-system`). 32 | - `helm_release` (String) Helm release of cilium installation (Default: `cilium`). 33 | -------------------------------------------------------------------------------- /templates/resources/cilium.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium Resource - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Install resource for Cilium. This is equivalent to cilium cli: cilium install, cilium upgrade and cilium uninstall: It manages cilium helm chart 7 | --- 8 | 9 | {{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. 10 | 11 | For example, the {{ SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} 12 | 13 | # cilium (Resource) 14 | 15 | Install resource for Cilium. This is equivalent to cilium cli: `cilium install`, `cilium upgrade` and `cilium uninstall`: It manages cilium helm chart 16 | 17 | ## Example Usage 18 | 19 | {{tffile "examples/resources/cilium/example_1.tf"}} 20 | 21 | * More examples: 22 | * AWS: https://github.com/tf-cilium/terraform-eks-cilium 23 | * Azure: https://github.com/tf-cilium/terraform-aks-cilium 24 | * GCP: https://github.com/tf-cilium/terraform-gke-cilium 25 | * Kind: https://github.com/tf-cilium/terraform-kind-cilium 26 | 27 | 28 | 29 | ## Schema 30 | 31 | ### Optional 32 | 33 | - `data_path` (String) Datapath mode to use { tunnel | native | aws-eni | gke | azure | aks-byocni } (Default: `autodetected`). 34 | - `repository` (String) Helm chart repository to download Cilium charts from (Default: `https://helm.cilium.io`). 35 | - `reset` (Boolean) When upgrading, reset the helm values to the ones built into the chart (Default: `false`). 36 | - `reuse` (Boolean) When upgrading, reuse the helm values from the latest release unless any overrides from are set from other flags. This option takes precedence over HelmResetValues (Default: `true`). 37 | - `set` (List of String) Set helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2 (Default: `[]`). 38 | - `values` (String) values in raw yaml to pass to helm. (Default: `empty`). 39 | - `version` (String) Version of Cilium (Default: `v1.14.5`). 40 | - `wait` (Boolean) Wait for Cilium status is ok (Default: `true`). 41 | 42 | ### Read-Only 43 | 44 | - `id` (String) Cilium install identifier 45 | - `helm_values` (String) Helm values (`helm get values -n kube-system cilium`) 46 | - `ca` (Object, sensitive) Cilium certificates value, Format: `{crt: "b64...", key: "b64.."}` (Equivalent to `kubectl get secret cilium-ca -n kube-system -o yaml`) 47 | -------------------------------------------------------------------------------- /templates/resources/clustermesh.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium_clustermesh Resource - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Cluster Mesh resource. This is equivalent to cilium cli: cilium clustermesh enable and cilium clustermesh disable: It manages the activation of Cluster Mesh on one Kubernetes cluster. 7 | --- 8 | 9 | {{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. 10 | 11 | For example, the {{ SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} 12 | 13 | # cilium_clustermesh (Resource) 14 | 15 | Cluster Mesh resource. This is equivalent to cilium cli: `cilium clustermesh enable` and `cilium clustermesh disable`: It manages the activation of Cluster Mesh on one Kubernetes cluster. 16 | 17 | ## Example Usage 18 | 19 | {{tffile "examples/resources/clustermesh/example_1.tf"}} 20 | 21 | * More examples: 22 | * https://github.com/tf-cilium/terraform-kind-cilium-clustermesh 23 | * https://github.com/littlejo/terraform-provider-cilium/tree/main/.github/tf/clustermesh 24 | 25 | 26 | 27 | ## Schema 28 | 29 | ### Optional 30 | 31 | - `enable_external_workloads` (Boolean) Enable support for external workloads, such as VMs (Default: `false`). 32 | - `enable_kv_store_mesh` (Boolean) Enable kvstoremesh, an extension which caches remote cluster information in the local kvstore (Cilium >=1.14 only) (Default: `false`). 33 | - `service_type` (String) Type of Kubernetes service to expose control plane { LoadBalancer | NodePort | ClusterIP } (Default: `autodetected`). 34 | - `wait` (Boolean) Wait Cluster Mesh status is ok (Default: `true`). 35 | 36 | ### Read-Only 37 | 38 | - `id` (String) Cilium ClusterMesh identifier 39 | -------------------------------------------------------------------------------- /templates/resources/clustermesh_connection.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium_clustermesh_connection Resource - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Cluster Mesh connection resource. This is equivalent to cilium cli: cilium clustermesh connect and cilium clustermesh disconnect: It manages the connections between two Kubernetes clusters. 7 | --- 8 | 9 | {{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. 10 | 11 | For example, the {{ SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} 12 | 13 | # cilium_clustermesh_connection (Resource) 14 | 15 | Cluster Mesh connection resource. This is equivalent to cilium cli: `cilium clustermesh connect` and `cilium clustermesh disconnect`: It manages the connections between two Kubernetes clusters. 16 | 17 | ## Example Usage 18 | 19 | {{tffile "examples/resources/clustermesh_connection/example_1.tf"}} 20 | 21 | * More examples: 22 | * https://github.com/tf-cilium/terraform-kind-cilium-clustermesh 23 | * https://github.com/littlejo/terraform-provider-cilium/tree/main/.github/tf/clustermesh 24 | 25 | 26 | 27 | ## Schema 28 | 29 | ### Optional 30 | 31 | - `destination_contexts` (List of String) Kubernetes configuration contexts of destination clusters 32 | - `connection_mode` (String) Connection Mode { `unicast` | `bidirectional` | `mesh` } (Default: `bidirectional`). 33 | - `parallel` (Number) Number of parallel connections of destination clusters (Default: `1`). 34 | 35 | ### Read-Only 36 | 37 | - `id` (String) Cilium ClusterMesh Connection identifier 38 | -------------------------------------------------------------------------------- /templates/resources/config.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium_config Resource - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Config resource for Cilium. This is equivalent to cilium cli: cilium config: It manages the cilium Kubernetes ConfigMap resource 7 | --- 8 | 9 | {{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. 10 | 11 | For example, the {{ SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} 12 | 13 | # cilium_config (Resource) 14 | 15 | Config resource for Cilium. This is equivalent to cilium cli: `cilium config`: It manages the cilium Kubernetes ConfigMap resource 16 | 17 | ## Example Usage 18 | 19 | {{tffile "examples/resources/config/example_1.tf"}} 20 | 21 | 22 | 23 | ## Schema 24 | 25 | ### Required 26 | 27 | - `key` (String) Key of the config 28 | - `value` (String) Value of the key 29 | 30 | ### Optional 31 | 32 | - `restart` (Boolean) Restart Cilium pods (Default: `true`). 33 | 34 | ### Read-Only 35 | 36 | - `id` (String) Cilium config identifier 37 | -------------------------------------------------------------------------------- /templates/resources/hubble.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium_hubble Resource - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Hubble resource for Cilium. This is equivalent to cilium cli: cilium hubble: It manages cilium hubble 7 | --- 8 | 9 | {{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. 10 | 11 | For example, the {{ SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} 12 | 13 | # cilium_hubble (Resource) 14 | 15 | Hubble resource for Cilium. This is equivalent to cilium cli: `cilium hubble`: It manages cilium hubble 16 | 17 | ## Example Usage 18 | 19 | {{tffile "examples/resources/hubble/example_1.tf"}} 20 | 21 | 22 | 23 | ## Schema 24 | 25 | ### Optional 26 | 27 | - `relay` (Boolean) Deploy Hubble Relay (Default: `true`). 28 | - `ui` (Boolean) Enable Hubble UI (Default: `false`). 29 | 30 | ### Read-Only 31 | 32 | - `id` (String) Cilium hubble identifier 33 | -------------------------------------------------------------------------------- /templates/resources/kubeproxy_free.md.tmpl: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "cilium_kubeproxy_free Resource - terraform-provider-cilium" 4 | subcategory: "" 5 | description: |- 6 | Disable Kube-Proxy DaemonSet, equivalent to: kubectl -n kube-system patch daemonset kube-proxy -p '"spec": {"template": {"spec": {"nodeSelector": {"non-existing": "true"}}}}'. 7 | --- 8 | 9 | {{/* This template serves as a starting point for documentation generation, and can be customized with hardcoded values and/or doc gen templates. 10 | 11 | For example, the {{ SchemaMarkdown }} template can be used to replace manual schema documentation if descriptions of schema attributes are added in the provider source code. */ -}} 12 | 13 | # cilium_kubeproxy_free (Resource) 14 | 15 | Disable Kube-Proxy DaemonSet, equivalent to: `kubectl -n kube-system patch daemonset kube-proxy -p '"spec": {"template": {"spec": {"nodeSelector": {"non-existing": "true"}}}}'`. 16 | 17 | 18 | 19 | ## Schema 20 | 21 | ### Optional 22 | 23 | - `name` (String) Name of DaemonSet (Default: `kube-proxy`). 24 | - `namespace` (String) Namespace in which to install (Default: `kube-system`). 25 | 26 | ### Read-Only 27 | 28 | - `id` (String) kube-proxy free identifier. 29 | -------------------------------------------------------------------------------- /terraform-registry-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "metadata": { 4 | "protocol_versions": ["6.0"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tools/tools.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) HashiCorp, Inc. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | //go:build tools 5 | 6 | package tools 7 | 8 | import ( 9 | // Documentation generation 10 | _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs" 11 | ) 12 | --------------------------------------------------------------------------------