Skip to content

Commit

Permalink
simplify sysctls handling, fix tests, add documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
rmanyari committed Jul 21, 2020
1 parent fa28761 commit 594fd80
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 151 deletions.
129 changes: 7 additions & 122 deletions google-beta/node_config.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package google

import (
"math"
"regexp"
"strconv"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
containerBeta "google.golang.org/api/container/v1beta1"
Expand All @@ -20,23 +16,6 @@ var defaultOauthScopes = []string{
"https://www.googleapis.com/auth/trace.append",
}

// This validates for a tuple-3 of positive integers. Spaces and tabs are supported as separators
var tcpMemoryRegexp = regexp.MustCompile(`^([1-9][0-9]+|0)[ \t]+([1-9][0-9]+|0)[ \t]+([1-9][0-9]+|0)$`)

// Keep track of the original sysctl keys since we replace dots by underscores to make the keys more TF idiomatic.
// Ref: https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/NodeConfig#LinuxNodeConfig
var sysAttrsMap = map[string]string{
"net_core_netdev_max_backlog": "net.core.netdev_max_backlog",
"net_core_rmem_max": "net.core.rmem_max",
"net_core_wmem_default": "net.core.wmem_default",
"net_core_wmem_max": "net.core.wmem_max",
"net_core_optmem_max": "net.core.optmem_max",
"net_core_somaxconn": "net.core.somaxconn",
"net_ipv4_tcp_rmem": "net.ipv4.tcp_rmem",
"net_ipv4_tcp_wmem": "net.ipv4.tcp_wmem",
"net_ipv4_tcp_tw_reuse": "net.ipv4.tcp_tw_reuse",
}

func schemaNodeConfig() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Expand Down Expand Up @@ -290,61 +269,9 @@ func schemaNodeConfig() *schema.Schema {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"sysctls": {
Type: schema.TypeList,
Type: schema.TypeMap,
Required: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"net_core_netdev_max_backlog": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IntBetween(1, math.MaxInt32),
},
"net_core_rmem_max": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IntBetween(1, math.MaxInt32),
},
"net_core_wmem_default": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IntBetween(1, math.MaxInt32),
},
"net_core_wmem_max": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IntBetween(1, math.MaxInt32),
},
"net_core_optmem_max": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IntBetween(1, math.MaxInt32),
},
"net_core_somaxconn": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IntBetween(128, math.MaxInt32),
},
"net_ipv4_tcp_rmem": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringMatch(
tcpMemoryRegexp,
"net_ipv4_tcp_rmem must be a tuple-3 of positive integers separated by spaces and or tabs"),
},
"net_ipv4_tcp_wmem": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringMatch(
tcpMemoryRegexp,
"net_ipv4_tcp_wmem must be a tuple-3 of positive integers separated by spaces and or tabs"),
},
"net_ipv4_tcp_tw_reuse": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IntBetween(0, 1),
},
},
},
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
Expand Down Expand Up @@ -549,35 +476,12 @@ func expandLinuxNodeConfig(v interface{}) *containerBeta.LinuxNodeConfig {
if !ok {
return nil
}
sysCfgList := sysCfgRaw.([]interface{})
if len(sysCfgList) == 0 {
return nil
}
sysCfg := sysCfgList[0].(map[string]interface{})
sysctls := make(map[string]string)
for k, v := range sysCfg {
var casted string
if i, ok := v.(int); ok {
casted = strconv.Itoa(i)
}
if s, ok := v.(string); ok {
casted = s
}
// So far the schema has only strings and ints.
// If we get anything other than that we skip it.
// If we ever support more types than that, we
// will need to add support for it here.
if casted == "" {
continue
}
// Lookup the actual sysctl supported key name
// to be sent to GCP.
if sysK, ok := sysAttrsMap[k]; ok {
sysctls[sysK] = casted
}
m := make(map[string]string)
for k, v := range sysCfgRaw.(map[string]interface{}) {
m[k] = v.(string)
}
return &containerBeta.LinuxNodeConfig{
Sysctls: sysctls,
Sysctls: m,
}
}

Expand Down Expand Up @@ -686,27 +590,8 @@ func flattenKubeletConfig(c *containerBeta.NodeKubeletConfig) []map[string]inter
func flattenLinuxNodeConfig(c *containerBeta.LinuxNodeConfig) []map[string]interface{} {
result := []map[string]interface{}{}
if c != nil {
// We are getting the sysctl keys in the Linux format, that is
// with dots in the name, let's replace those with the internal
// TF keys which use underscores.
//
// To get there, let's simply flip our sysAttrsMap and perform
// the lookups.
flipped := func() map[string]string {
m := make(map[string]string)
for k, v := range sysAttrsMap {
m[v] = k
}
return m
}()
m := make(map[string]interface{})
for sysK, v := range c.Sysctls {
if k, ok := flipped[sysK]; ok {
m[k] = v
}
}
result = append(result, map[string]interface{}{
"sysctls": m,
"sysctls": c.Sysctls,
})
}
return result
Expand Down
49 changes: 20 additions & 29 deletions google-beta/resource_container_node_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,6 @@ func TestAccContainerNodePool_withKubeletConfig(t *testing.T) {
Steps: []resource.TestStep{
{
Config: testAccContainerNodePool_withKubeletConfig(cluster, np, "static"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("google_container_node_pool.with_kubelet_config",
"node_config.0.kubelet_config.0.cpu_manager_policy", "static"),
resource.TestCheckResourceAttr("google_container_node_pool.with_kubelet_config",
"node_config.0.kubelet_config.0.cpu_cfs_quota", "true"),
resource.TestCheckResourceAttr("google_container_node_pool.with_kubelet_config",
"node_config.0.kubelet_config.0.cpu_cfs_quota_period", "100us"),
),
},
{
ResourceName: "google_container_node_pool.with_kubelet_config",
Expand Down Expand Up @@ -300,17 +292,16 @@ func TestAccContainerNodePool_withLinuxNodeConfig(t *testing.T) {
CheckDestroy: testAccCheckContainerClusterDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccContainerNodePool_withLinuxNodeConfig(cluster, np, 100, 128, "10 100 1000", 1),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("google_container_node_pool.with_kubelet_config",
"node_config.0.linux_node_config.0.sysctls.0.net_core_netdev_max_backlog", "100"),
resource.TestCheckResourceAttr("google_container_node_pool.with_kubelet_config",
"node_config.0.linux_node_config.0.sysctls.0.net_core_somaxconn", "128"),
resource.TestCheckResourceAttr("google_container_node_pool.with_kubelet_config",
"node_config.0.linux_node_config.0.sysctls.0.net_ipv4_tcp_rmem", "10 100 1000"),
resource.TestCheckResourceAttr("google_container_node_pool.with_kubelet_config",
"node_config.0.linux_node_config.0.sysctls.0.net_ipv4_tcp_tw_reuse", "1"),
),
Config: testAccContainerNodePool_withLinuxNodeConfig(cluster, np, 10000, 12800, "1000 20000 100000", 1),
},
{
ResourceName: "google_container_node_pool.with_linux_node_config",
ImportState: true,
ImportStateVerify: true,
},
// Perform an update.
{
Config: testAccContainerNodePool_withLinuxNodeConfig(cluster, np, 10000, 12800, "1000 20000 200000", 1),
},
{
ResourceName: "google_container_node_pool.with_linux_node_config",
Expand Down Expand Up @@ -1401,16 +1392,16 @@ resource "google_container_node_pool" "with_linux_node_config" {
node_config {
image_type = "COS_CONTAINERD"
linux_node_config {
sysctls {
net_core_netdev_max_backlog = %d
net_core_rmem_max = 100
net_core_wmem_default = 100
net_core_wmem_max = 200
net_core_optmem_max = 100
net_core_somaxconn = %d
net_ipv4_tcp_rmem = "%s"
net_ipv4_tcp_wmem = "%s"
net_ipv4_tcp_tw_reuse = %d
sysctls = {
"net.core.netdev_max_backlog" = "%d"
"net.core.rmem_max" = 10000
"net.core.wmem_default" = 10000
"net.core.wmem_max" = 20000
"net.core.optmem_max" = 10000
"net.core.somaxconn" = %d
"net.ipv4.tcp_rmem" = "%s"
"net.ipv4.tcp_wmem" = "%s"
"net.ipv4.tcp_tw_reuse" = %d
}
}
oauth_scopes = [
Expand Down
21 changes: 21 additions & 0 deletions website/docs/r/container_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,27 @@ recommended. Structure is documented below.
* `workload_metadata_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Metadata configuration to expose to workloads on the node pool.
Structure is documented below.

* `kubelet_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Kubelet configuration, currently supported attributes can be found [here](https://cloud.google.com/sdk/gcloud/reference/beta/container/node-pools/create#--system-config-from-file).

```
kubelet_config {
cpu_manager_policy = "static"
cpu_cfs_quota = true
cpu_cfs_quota_period = "100us"
}
```

* `linux_node_config` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Linux node configuration, currently supported attributes can be found [here](https://cloud.google.com/sdk/gcloud/reference/beta/container/node-pools/create#--system-config-from-file). Note that validations happen all server side. All attributes are optional. Usage example below:

```hcl
linux_node_config {
sysctls = {
"net.core.netdev_max_backlog" = "10000"
"net.core.rmem_max" = "10000"
}
}
```

The `guest_accelerator` block supports:

* `type` (Required) - The accelerator type resource to expose to this instance. E.g. `nvidia-tesla-k80`.
Expand Down

0 comments on commit 594fd80

Please sign in to comment.