Skip to content

Commit

Permalink
🐛 (Azure Kubernete resource.) Update the validation logic of network_…
Browse files Browse the repository at this point in the history
…profile setting.

The docker_bridge_cidr, dns_service_ip, service_cidr should be either all empty or all non-empty.

Closes #1648
  • Loading branch information
metacpp committed Aug 3, 2018
1 parent 0542c72 commit 6397658
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 127 deletions.
26 changes: 26 additions & 0 deletions azurerm/resource_arm_kubernetes_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,32 @@ func resourceArmKubernetesCluster() *schema.Resource {
State: schema.ImportStatePassthrough,
},

CustomizeDiff: func(diff *schema.ResourceDiff, v interface{}) error {
if v, exists := diff.GetOk("network_profile"); exists {
rawProfiles := v.([]interface{})
if len(rawProfiles) == 0 {
return nil
}

// then ensure the conditionally-required fields are set
profile := rawProfiles[0].(map[string]interface{})
networkPlugin := profile["network_plugin"].(string)

if networkPlugin == "kubenet" || networkPlugin == "azure" {
dockerBridgeCidr := profile["docker_bridge_cidr"].(string)
dnsServiceIP := profile["dns_service_ip"].(string)
serviceCidr := profile["service_cidr"].(string)

if !((dockerBridgeCidr == "" && dnsServiceIP == "" && serviceCidr == "") ||
(dockerBridgeCidr != "" && dnsServiceIP != "" && serviceCidr != "")) {
return fmt.Errorf("`docker_bridge_cidr`, `dns_service_ip` and `service_cidr` should all be empty or neither should be empty.")
}
}
}

return nil
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Expand Down
166 changes: 42 additions & 124 deletions azurerm/resource_arm_kubernetes_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,9 @@ func TestAccAzureRMKubernetesCluster_advancedNetworkingKubenet(t *testing.T) {
ri := acctest.RandInt()
clientId := os.Getenv("ARM_CLIENT_ID")
clientSecret := os.Getenv("ARM_CLIENT_SECRET")
config := testAccAzureRMKubernetesCluster_advancedNetworkingKubenet(ri, clientId, clientSecret, testLocation())
config := testAccAzureRMKubernetesCluster_advancedNetworking(
ri, clientId, clientSecret, testLocation(),
"kubenet", "", "", "")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand All @@ -206,7 +208,9 @@ func TestAccAzureRMKubernetesCluster_advancedNetworkingKubenetComplete(t *testin
ri := acctest.RandInt()
clientId := os.Getenv("ARM_CLIENT_ID")
clientSecret := os.Getenv("ARM_CLIENT_SECRET")
config := testAccAzureRMKubernetesCluster_advancedNetworkingKubenetComplete(ri, clientId, clientSecret, testLocation())
config := testAccAzureRMKubernetesCluster_advancedNetworking(
ri, clientId, clientSecret, testLocation(),
"kubenet", "10.10.0.10", "172.18.0.1/16", "10.10.0.0/16")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand All @@ -229,7 +233,34 @@ func TestAccAzureRMKubernetesCluster_advancedNetworkingAzure(t *testing.T) {
ri := acctest.RandInt()
clientId := os.Getenv("ARM_CLIENT_ID")
clientSecret := os.Getenv("ARM_CLIENT_SECRET")
config := testAccAzureRMKubernetesCluster_advancedNetworkingAzure(ri, clientId, clientSecret, testLocation())
config := testAccAzureRMKubernetesCluster_advancedNetworking(
ri, clientId, clientSecret, testLocation(),
"azure", "", "", "")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMKubernetesClusterDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMKubernetesClusterExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "network_profile.0.network_plugin", "azure"),
),
},
},
})
}

func TestAccAzureRMKubernetesCluster_advancedNetworkingAzureComplete(t *testing.T) {
resourceName := "azurerm_kubernetes_cluster.test"
ri := acctest.RandInt()
clientId := os.Getenv("ARM_CLIENT_ID")
clientSecret := os.Getenv("ARM_CLIENT_SECRET")
config := testAccAzureRMKubernetesCluster_advancedNetworking(
ri, clientId, clientSecret, testLocation(),
"azure", "10.10.0.10", "172.18.0.1/16", "10.10.0.0/16")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand Down Expand Up @@ -410,7 +441,9 @@ resource "azurerm_kubernetes_cluster" "test" {
`, rInt, location, rInt, rInt, rInt, clientId, clientSecret)
}

func testAccAzureRMKubernetesCluster_advancedNetworkingKubenet(rInt int, clientId string, clientSecret string, location string) string {
func testAccAzureRMKubernetesCluster_advancedNetworking(rInt int, clientId string, clientSecret string, location string,
networkProfile string, dnsServiceIp string, dockerBridgeCidr string,
serviceCidr string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
Expand Down Expand Up @@ -463,128 +496,13 @@ resource "azurerm_kubernetes_cluster" "test" {
}
network_profile {
network_plugin = "kubenet"
}
}
`, rInt, location, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret)
}

func testAccAzureRMKubernetesCluster_advancedNetworkingKubenetComplete(rInt int, clientId string, clientSecret string, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}
resource "azurerm_virtual_network" "test" {
name = "acctestvirtnet%d"
address_space = ["10.1.0.0/16"]
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
tags {
environment = "Testing"
network_plugin = "%s"
dns_service_ip = "%s"
docker_bridge_cidr = "%s"
service_cidr = "%s"
}
}
resource "azurerm_subnet" "test" {
name = "acctestsubnet%d"
resource_group_name = "${azurerm_resource_group.test.name}"
virtual_network_name = "${azurerm_virtual_network.test.name}"
address_prefix = "10.1.0.0/24"
}
resource "azurerm_kubernetes_cluster" "test" {
name = "acctestaks%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
dns_prefix = "acctestaks%d"
kubernetes_version = "1.7.7"
linux_profile {
admin_username = "acctestuser%d"
ssh_key {
key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld"
}
}
agent_pool_profile {
name = "default"
count = "2"
vm_size = "Standard_DS2_v2"
vnet_subnet_id = "${azurerm_subnet.test.id}"
}
service_principal {
client_id = "%s"
client_secret = "%s"
}
network_profile {
network_plugin = "kubenet"
}
}
`, rInt, location, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret)
}

func testAccAzureRMKubernetesCluster_advancedNetworkingAzure(rInt int, clientId string, clientSecret string, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}
resource "azurerm_virtual_network" "test" {
name = "acctestvirtnet%d"
address_space = ["10.1.0.0/16"]
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
tags {
environment = "Testing"
}
}
resource "azurerm_subnet" "test" {
name = "acctestsubnet%d"
resource_group_name = "${azurerm_resource_group.test.name}"
virtual_network_name = "${azurerm_virtual_network.test.name}"
address_prefix = "10.1.0.0/24"
}
resource "azurerm_kubernetes_cluster" "test" {
name = "acctestaks%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
dns_prefix = "acctestaks%d"
kubernetes_version = "1.7.7"
linux_profile {
admin_username = "acctestuser%d"
ssh_key {
key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld"
}
}
agent_pool_profile {
name = "default"
count = "2"
vm_size = "Standard_DS2_v2"
vnet_subnet_id = "${azurerm_subnet.test.id}"
}
service_principal {
client_id = "%s"
client_secret = "%s"
}
network_profile {
network_plugin = "azure"
}
}
`, rInt, location, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret)
`, rInt, location, rInt, rInt, rInt, rInt, rInt, clientId, clientSecret, networkProfile, dnsServiceIp, dockerBridgeCidr, serviceCidr)
}

func testCheckAzureRMKubernetesClusterExists(name string) resource.TestCheckFunc {
Expand Down
6 changes: 3 additions & 3 deletions website/docs/r/kubernetes_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,13 @@ The following arguments are supported:

-> **NOTE:** When `network_plugin` is set to `azure` - the `vnet_subnet_id` field in the `agent_pool_profile` block must be set.

* `service_cidr` - (Optional) The Network Range used by the Kubernetes service. Changing this forces a new resource to be created.
* `service_cidr` - (Optional) The Network Range used by the Kubernetes service. This field can only be set together with `dns_service_ip` and `docker_bridge_cidr`. Changing this forces a new resource to be created.

~> **NOTE:** This range should not be used by any network element on or connected to this VNet. Service address CIDR must be smaller than /12.

* `dns_service_ip` - (Optional) IP address within the Kubernetes service address range that will be used by cluster service discovery (kube-dns). Changing this forces a new resource to be created.
* `dns_service_ip` - (Optional) IP address within the Kubernetes service address range that will be used by cluster service discovery (kube-dns). This field can only be set together with `service_cidr` and `docker_bridge_cidr`. Changing this forces a new resource to be created.

* `docker_bridge_cidr` - (Optional) IP address (in CIDR notation) used as the Docker bridge IP address on nodes. Changing this forces a new resource to be created.
* `docker_bridge_cidr` - (Optional) IP address (in CIDR notation) used as the Docker bridge IP address on nodes. This field can only be set together with `service_cidr` and `dns_service_ip`. Changing this forces a new resource to be created.

* `pod_cidr` - (Optional) The CIDR to use for pod IP addresses. This field can only be set when `network_plugin` is set to `kubenet`. Changing this forces a new resource to be created.

Expand Down

0 comments on commit 6397658

Please sign in to comment.