diff --git a/.github/workflows/labeled-pr-testing.yml b/.github/workflows/labeled-pr-testing.yml index 1ee7162..53ebf18 100644 --- a/.github/workflows/labeled-pr-testing.yml +++ b/.github/workflows/labeled-pr-testing.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} - - uses: actions/setup-go@v3 + - uses: actions/setup-go@v4 with: go-version: 1.19 diff --git a/docs/resources/cluster.md b/docs/resources/cluster.md index 2f8a67f..e7cb6d0 100644 --- a/docs/resources/cluster.md +++ b/docs/resources/cluster.md @@ -19,10 +19,10 @@ To override the node image used: ```hcl provider "kind" {} -# Create a cluster with kind of the name "test-cluster" with kubernetes version v1.16.1 +# Create a cluster with kind of the name "test-cluster" with kubernetes version v1.27.1 resource "kind_cluster" "default" { name = "test-cluster" - node_image = "kindest/node:v1.16.1" + node_image = "kindest/node:v1.27.1" } ``` @@ -68,10 +68,10 @@ To override the default kind config: ```hcl provider "kind" {} -# creating a cluster with kind of the name "test-cluster" with kubernetes version v1.18.4 and two nodes +# creating a cluster with kind of the name "test-cluster" with kubernetes version v1.27.1 and two nodes resource "kind_cluster" "default" { name = "test-cluster" - node_image = "kindest/node:v1.18.4" + node_image = "kindest/node:v1.27.1" kind_config { kind = "Cluster" api_version = "kind.x-k8s.io/v1alpha4" @@ -92,7 +92,7 @@ provider "kind" {} # Create a cluster with patches applied to the containerd config resource "kind_cluster" "default" { name = "test-cluster" - node_image = "kindest/node:v1.23.4" + node_image = "kindest/node:v1.27.1" kind_config = { containerd_config_patches = [ <<-TOML @@ -121,7 +121,7 @@ resource "kind_cluster" "default" { ## Argument Reference * `name` - (Required) The kind name that is given to the created cluster. -* `node_image` - (Optional) The node_image that kind will use (ex: kindest/node:v1.23.4). +* `node_image` - (Optional) The node_image that kind will use (ex: kindest/node:v1.27.1). * `wait_for_ready` - (Optional) Defines wether or not the provider will wait for the control plane to be ready. Defaults to false. * `kind_config` - (Optional) The kind_config that kind will use. * `kubeconfig_path` - kubeconfig path set after the the cluster is created or by the user to override defaults. diff --git a/example/main.tf b/example/main.tf index b11faec..0fc47c9 100644 --- a/example/main.tf +++ b/example/main.tf @@ -1,3 +1,12 @@ +terraform { + required_providers { + kind = { + source = "tehcyx/kind" + version = "~> 0.0.18" + } + } +} + provider "kind" { } @@ -14,7 +23,6 @@ resource "kind_cluster" "default" { node { role = "worker" - image = "kindest/node:v1.23.4" } node { diff --git a/go.mod b/go.mod index b730c01..5688755 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1 github.com/pelletier/go-toml v1.9.5 k8s.io/client-go v12.0.0+incompatible - sigs.k8s.io/kind v0.18.0 + sigs.k8s.io/kind v0.19.0 ) require ( diff --git a/go.sum b/go.sum index 2150526..9b4e25f 100644 --- a/go.sum +++ b/go.sum @@ -742,8 +742,8 @@ k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/kind v0.18.0 h1:ahgZdVV1pdhXlYe1f+ztISakT23KdrBl/NFY9JMygzs= -sigs.k8s.io/kind v0.18.0/go.mod h1:Qqp8AiwOlMZmJWs37Hgs31xcbiYXjtXlRBSftcnZXQk= +sigs.k8s.io/kind v0.19.0 h1:ZSUh6/kpab6fiowT6EqL4k8xSbedI2NWxyuUOtoPFe4= +sigs.k8s.io/kind v0.19.0/go.mod h1:aBlbxg08cauDgZ612shr017/rZwqd7AS563FvpWKPVs= sigs.k8s.io/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/kind/resource_cluster.go b/kind/resource_cluster.go index 525c52f..a6103e2 100644 --- a/kind/resource_cluster.go +++ b/kind/resource_cluster.go @@ -33,7 +33,7 @@ func resourceCluster() *schema.Resource { }, "node_image": { Type: schema.TypeString, - Description: `The node_image that kind will use (ex: kindest/node:v1.23.4).`, + Description: `The node_image that kind will use (ex: kindest/node:v1.26.4).`, Optional: true, ForceNew: true, Computed: true, @@ -163,7 +163,7 @@ func resourceKindClusterRead(d *schema.ResourceData, meta interface{}) error { return err } - if _, ok := d.GetOkExists("kubeconfig_path"); !ok { + if _, ok := d.GetOk("kubeconfig_path"); !ok { exportPath := fmt.Sprintf("%s%s%s-config", currentPath, string(os.PathSeparator), name) err = provider.ExportKubeConfig(name, exportPath, false) if err != nil { diff --git a/kind/resource_cluster_test.go b/kind/resource_cluster_test.go index 950c913..e0ff471 100644 --- a/kind/resource_cluster_test.go +++ b/kind/resource_cluster_test.go @@ -24,7 +24,7 @@ func testSweepKindCluster(name string) error { return nil } -const nodeImage = "kindest/node:v1.24.6" +const nodeImage = "kindest/node:v1.26.4@sha256:f4c0d87be03d6bea69f5e5dc0adb678bb498a190ee5c38422bf751541cebe92e" func TestAccCluster(t *testing.T) { resourceName := "kind_cluster.test" @@ -167,7 +167,7 @@ func TestAccClusterConfigBase(t *testing.T) { ), }, { - Config: testAccClusterConfigAndRuntimeConfig(clusterName), + Config: testAccClusterConfigAndExtraWithNetworkValues(clusterName), Check: resource.ComposeTestCheckFunc( testAccCheckClusterCreate(resourceName), resource.TestCheckResourceAttr(resourceName, "name", clusterName), @@ -176,9 +176,24 @@ func TestAccClusterConfigBase(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "kind_config.#", "1"), resource.TestCheckResourceAttr(resourceName, "kind_config.0.kind", "Cluster"), resource.TestCheckResourceAttr(resourceName, "kind_config.0.api_version", "kind.x-k8s.io/v1alpha4"), + resource.TestCheckResourceAttr(resourceName, "kind_config.0.networking.#", "1"), + resource.TestCheckResourceAttr(resourceName, "kind_config.0.networking.0.api_server_address", "127.0.0.1"), + resource.TestCheckResourceAttr(resourceName, "kind_config.0.networking.0.api_server_port", "6443"), + ), + }, + { + Config: testAccClusterConfigAndRuntimeConfig(clusterName), + Check: resource.ComposeTestCheckFunc( + testAccCheckClusterCreate(resourceName), + resource.TestCheckResourceAttr(resourceName, "name", clusterName), + resource.TestCheckNoResourceAttr(resourceName, "node_image"), + resource.TestCheckResourceAttr(resourceName, "wait_for_ready", "true"), + resource.TestCheckResourceAttr(resourceName, "kind_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "kind_config.0.kind", "Cluster"), + resource.TestCheckResourceAttr(resourceName, "kind_config.0.api_version", "kind.x-k8s.io/v1alpha4"), resource.TestCheckResourceAttr(resourceName, "kind_config.0.runtime_config.#", "1"), - resource.TestCheckResourceAttr(resourceName, "kind_config.0.runtime_config.0", "api/all"), - resource.TestCheckResourceAttr(resourceName, "kind_config.0.runtime_config.0.api/all", "false"), + resource.TestCheckResourceAttr(resourceName, "kind_config.0.runtime_config.0", "api_alpha"), + resource.TestCheckResourceAttr(resourceName, "kind_config.0.runtime_config.0.api_alpha", "false"), ), }, { @@ -187,13 +202,13 @@ func TestAccClusterConfigBase(t *testing.T) { testAccCheckClusterCreate(resourceName), resource.TestCheckResourceAttr(resourceName, "name", clusterName), resource.TestCheckNoResourceAttr(resourceName, "node_image"), - resource.TestCheckResourceAttr(resourceName, "wait_for_ready", "false"), + resource.TestCheckResourceAttr(resourceName, "wait_for_ready", "true"), resource.TestCheckResourceAttr(resourceName, "kind_config.#", "1"), resource.TestCheckResourceAttr(resourceName, "kind_config.0.kind", "Cluster"), resource.TestCheckResourceAttr(resourceName, "kind_config.0.api_version", "kind.x-k8s.io/v1alpha4"), resource.TestCheckResourceAttr(resourceName, "kind_config.0.feature_gates.#", "1"), - resource.TestCheckResourceAttr(resourceName, "kind_config.0.feature_gates.0", "CSIMigration"), - resource.TestCheckResourceAttr(resourceName, "kind_config.0.feature_gates.0.CSIMigration", "true"), + resource.TestCheckResourceAttr(resourceName, "kind_config.0.feature_gates.0", "CSINodeExpandSecret"), + resource.TestCheckResourceAttr(resourceName, "kind_config.0.feature_gates.0.CSINodeExpandSecret", "false"), ), }, }, @@ -724,7 +739,7 @@ resource "kind_cluster" "test" { `, name) } -func testAccClusterConfigAndRuntimeConfig(name string) string { +func testAccClusterConfigAndExtraWithNetworkValues(name string) string { return fmt.Sprintf(` resource "kind_cluster" "test" { name = "%s" @@ -733,8 +748,26 @@ resource "kind_cluster" "test" { kind = "Cluster" api_version = "kind.x-k8s.io/v1alpha4" - runtime_config { - "api/alpha": "false" + networking { + api_server_address = "127.0.0.1" + api_server_port = 6443 + } + } +} +`, name) +} + +func testAccClusterConfigAndRuntimeConfig(name string) string { + return fmt.Sprintf(` +resource "kind_cluster" "test" { + name = "%s" + wait_for_ready = true + kind_config { + kind = "Cluster" + api_version = "kind.x-k8s.io/v1alpha4" + + runtime_config = { + api_alpha = "false" } } } @@ -745,13 +778,13 @@ func testAccClusterConfigAndFeatureGates(name string) string { return fmt.Sprintf(` resource "kind_cluster" "test" { name = "%s" - wait_for_ready = false + wait_for_ready = true kind_config { kind = "Cluster" api_version = "kind.x-k8s.io/v1alpha4" - feature_gates { - "CSIMigration": "true" + feature_gates = { + CSINodeExpandSecret = "false" } } } diff --git a/kind/schema_kind_config.go b/kind/schema_kind_config.go index ac30eb4..89e197d 100644 --- a/kind/schema_kind_config.go +++ b/kind/schema_kind_config.go @@ -56,16 +56,12 @@ func kindConfigFields() map[string]*schema.Schema { "runtime_config": { Type: schema.TypeMap, Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, + Elem: &schema.Schema{Type: schema.TypeString}, }, "feature_gates": { Type: schema.TypeMap, Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, + Elem: &schema.Schema{Type: schema.TypeString}, }, } return forceNewAll(s) @@ -114,9 +110,7 @@ func kindConfigNodeFields() map[string]*schema.Schema { "labels": { Type: schema.TypeMap, Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, + Elem: &schema.Schema{Type: schema.TypeString}, }, "kubeadm_config_patches": { Type: schema.TypeList, diff --git a/kind/structure_kind_config.go b/kind/structure_kind_config.go index aaa1c47..4fe7128 100644 --- a/kind/structure_kind_config.go +++ b/kind/structure_kind_config.go @@ -42,14 +42,17 @@ func flattenKindConfig(d map[string]interface{}) *v1alpha4.Cluster { runtimeConfig := mapKeyIfExists(d, "runtime_config") if runtimeConfig != nil { - for k, v := range runtimeConfig.(map[string]string) { - obj.RuntimeConfig[k] = v + data := runtimeConfig.(map[string]interface{}) + for k, v := range data { + k = strings.ReplaceAll(k, "_", "/") // slash is not allowed in hcl, if there's an underscore replace with slash, e.g. `api_alpha` to `api/alpha` + obj.RuntimeConfig[k] = v.(string) } } featureGates := mapKeyIfExists(d, "features_gates") if featureGates != nil { - for k, v := range featureGates.(map[string]string) { + data := featureGates.(map[string]string) + for k, v := range data { if strings.ToLower(v) == "true" { obj.FeatureGates[k] = true } else {