github.com/peterbale/terraform@v0.9.0-beta2.0.20170315142748-5723acd55547/builtin/providers/google/resource_container_cluster_test.go (about) 1 package google 2 3 import ( 4 "fmt" 5 "testing" 6 7 "strconv" 8 9 "github.com/hashicorp/terraform/helper/acctest" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/terraform" 12 ) 13 14 func TestAccContainerCluster_basic(t *testing.T) { 15 resource.Test(t, resource.TestCase{ 16 PreCheck: func() { testAccPreCheck(t) }, 17 Providers: testAccProviders, 18 CheckDestroy: testAccCheckContainerClusterDestroy, 19 Steps: []resource.TestStep{ 20 resource.TestStep{ 21 Config: testAccContainerCluster_basic, 22 Check: resource.ComposeTestCheckFunc( 23 testAccCheckContainerCluster( 24 "google_container_cluster.primary"), 25 ), 26 }, 27 }, 28 }) 29 } 30 31 func TestAccContainerCluster_withAdditionalZones(t *testing.T) { 32 resource.Test(t, resource.TestCase{ 33 PreCheck: func() { testAccPreCheck(t) }, 34 Providers: testAccProviders, 35 CheckDestroy: testAccCheckContainerClusterDestroy, 36 Steps: []resource.TestStep{ 37 resource.TestStep{ 38 Config: testAccContainerCluster_withAdditionalZones, 39 Check: resource.ComposeTestCheckFunc( 40 testAccCheckContainerCluster( 41 "google_container_cluster.with_additional_zones"), 42 ), 43 }, 44 }, 45 }) 46 } 47 48 func TestAccContainerCluster_withVersion(t *testing.T) { 49 resource.Test(t, resource.TestCase{ 50 PreCheck: func() { testAccPreCheck(t) }, 51 Providers: testAccProviders, 52 CheckDestroy: testAccCheckContainerClusterDestroy, 53 Steps: []resource.TestStep{ 54 resource.TestStep{ 55 Config: testAccContainerCluster_withVersion, 56 Check: resource.ComposeTestCheckFunc( 57 testAccCheckContainerCluster( 58 "google_container_cluster.with_version"), 59 ), 60 }, 61 }, 62 }) 63 } 64 65 func TestAccContainerCluster_withNodeConfig(t *testing.T) { 66 resource.Test(t, resource.TestCase{ 67 PreCheck: func() { testAccPreCheck(t) }, 68 Providers: testAccProviders, 69 CheckDestroy: testAccCheckContainerClusterDestroy, 70 Steps: []resource.TestStep{ 71 resource.TestStep{ 72 Config: testAccContainerCluster_withNodeConfig, 73 Check: resource.ComposeTestCheckFunc( 74 testAccCheckContainerCluster( 75 "google_container_cluster.with_node_config"), 76 ), 77 }, 78 }, 79 }) 80 } 81 82 func TestAccContainerCluster_withNodeConfigScopeAlias(t *testing.T) { 83 resource.Test(t, resource.TestCase{ 84 PreCheck: func() { testAccPreCheck(t) }, 85 Providers: testAccProviders, 86 CheckDestroy: testAccCheckContainerClusterDestroy, 87 Steps: []resource.TestStep{ 88 resource.TestStep{ 89 Config: testAccContainerCluster_withNodeConfigScopeAlias, 90 Check: resource.ComposeTestCheckFunc( 91 testAccCheckContainerCluster( 92 "google_container_cluster.with_node_config_scope_alias"), 93 ), 94 }, 95 }, 96 }) 97 } 98 99 func TestAccContainerCluster_network(t *testing.T) { 100 resource.Test(t, resource.TestCase{ 101 PreCheck: func() { testAccPreCheck(t) }, 102 Providers: testAccProviders, 103 CheckDestroy: testAccCheckContainerClusterDestroy, 104 Steps: []resource.TestStep{ 105 resource.TestStep{ 106 Config: testAccContainerCluster_networkRef, 107 Check: resource.ComposeTestCheckFunc( 108 testAccCheckContainerCluster( 109 "google_container_cluster.with_net_ref_by_url"), 110 testAccCheckContainerCluster( 111 "google_container_cluster.with_net_ref_by_name"), 112 ), 113 }, 114 }, 115 }) 116 } 117 118 func TestAccContainerCluster_backend(t *testing.T) { 119 resource.Test(t, resource.TestCase{ 120 PreCheck: func() { testAccPreCheck(t) }, 121 Providers: testAccProviders, 122 CheckDestroy: testAccCheckContainerClusterDestroy, 123 Steps: []resource.TestStep{ 124 resource.TestStep{ 125 Config: testAccContainerCluster_backendRef, 126 Check: resource.ComposeTestCheckFunc( 127 testAccCheckContainerCluster( 128 "google_container_cluster.primary"), 129 ), 130 }, 131 }, 132 }) 133 } 134 135 func testAccCheckContainerClusterDestroy(s *terraform.State) error { 136 config := testAccProvider.Meta().(*Config) 137 138 for _, rs := range s.RootModule().Resources { 139 if rs.Type != "google_container_cluster" { 140 continue 141 } 142 143 attributes := rs.Primary.Attributes 144 _, err := config.clientContainer.Projects.Zones.Clusters.Get( 145 config.Project, attributes["zone"], attributes["name"]).Do() 146 if err == nil { 147 return fmt.Errorf("Cluster still exists") 148 } 149 } 150 151 return nil 152 } 153 154 func testAccCheckContainerCluster(n string) resource.TestCheckFunc { 155 return func(s *terraform.State) error { 156 attributes, err := getResourceAttributes(n, s) 157 if err != nil { 158 return err 159 } 160 161 config := testAccProvider.Meta().(*Config) 162 cluster, err := config.clientContainer.Projects.Zones.Clusters.Get( 163 config.Project, attributes["zone"], attributes["name"]).Do() 164 if err != nil { 165 return err 166 } 167 168 if cluster.Name != attributes["name"] { 169 return fmt.Errorf("Cluster %s not found, found %s instead", attributes["name"], cluster.Name) 170 } 171 172 type clusterTestField struct { 173 tf_attr string 174 gcp_attr interface{} 175 } 176 177 clusterTests := []clusterTestField{ 178 {"initial_node_count", strconv.FormatInt(cluster.InitialNodeCount, 10)}, 179 {"master_auth.0.client_certificate", cluster.MasterAuth.ClientCertificate}, 180 {"master_auth.0.client_key", cluster.MasterAuth.ClientKey}, 181 {"master_auth.0.cluster_ca_certificate", cluster.MasterAuth.ClusterCaCertificate}, 182 {"master_auth.0.password", cluster.MasterAuth.Password}, 183 {"master_auth.0.username", cluster.MasterAuth.Username}, 184 {"zone", cluster.Zone}, 185 {"cluster_ipv4_cidr", cluster.ClusterIpv4Cidr}, 186 {"description", cluster.Description}, 187 {"endpoint", cluster.Endpoint}, 188 {"instance_group_urls", cluster.InstanceGroupUrls}, 189 {"logging_service", cluster.LoggingService}, 190 {"monitoring_service", cluster.MonitoringService}, 191 {"subnetwork", cluster.Subnetwork}, 192 {"node_config.0.machine_type", cluster.NodeConfig.MachineType}, 193 {"node_config.0.disk_size_gb", strconv.FormatInt(cluster.NodeConfig.DiskSizeGb, 10)}, 194 {"node_config.0.oauth_scopes", cluster.NodeConfig.OauthScopes}, 195 {"node_version", cluster.CurrentNodeVersion}, 196 } 197 198 // Remove Zone from additional_zones since that's what the resource writes in state 199 additionalZones := []string{} 200 for _, location := range cluster.Locations { 201 if location != cluster.Zone { 202 additionalZones = append(additionalZones, location) 203 } 204 } 205 clusterTests = append(clusterTests, clusterTestField{"additional_zones", additionalZones}) 206 207 // AddonsConfig is neither Required or Computed, so the API may return nil for it 208 if cluster.AddonsConfig != nil { 209 if cluster.AddonsConfig.HttpLoadBalancing != nil { 210 clusterTests = append(clusterTests, clusterTestField{"addons_config.0.http_load_balancing.0.disabled", strconv.FormatBool(cluster.AddonsConfig.HttpLoadBalancing.Disabled)}) 211 } 212 if cluster.AddonsConfig.HorizontalPodAutoscaling != nil { 213 clusterTests = append(clusterTests, clusterTestField{"addons_config.0.horizontal_pod_autoscaling.0.disabled", strconv.FormatBool(cluster.AddonsConfig.HorizontalPodAutoscaling.Disabled)}) 214 } 215 } 216 217 for _, attrs := range clusterTests { 218 if c := checkMatch(attributes, attrs.tf_attr, attrs.gcp_attr); c != "" { 219 return fmt.Errorf(c) 220 } 221 } 222 223 // Network has to be done separately in order to normalize the two values 224 tf, err := getNetworkNameFromSelfLink(attributes["network"]) 225 if err != nil { 226 return err 227 } 228 gcp, err := getNetworkNameFromSelfLink(cluster.Network) 229 if err != nil { 230 return err 231 } 232 if tf != gcp { 233 return fmt.Errorf(matchError("network", tf, gcp)) 234 } 235 236 return nil 237 } 238 } 239 240 func getResourceAttributes(n string, s *terraform.State) (map[string]string, error) { 241 rs, ok := s.RootModule().Resources[n] 242 if !ok { 243 return nil, fmt.Errorf("Not found: %s", n) 244 } 245 246 if rs.Primary.ID == "" { 247 return nil, fmt.Errorf("No ID is set") 248 } 249 250 return rs.Primary.Attributes, nil 251 } 252 253 func checkMatch(attributes map[string]string, attr string, gcp interface{}) string { 254 if gcpList, ok := gcp.([]string); ok { 255 return checkListMatch(attributes, attr, gcpList) 256 } 257 tf := attributes[attr] 258 if tf != gcp { 259 return matchError(attr, tf, gcp) 260 } 261 return "" 262 } 263 264 func checkListMatch(attributes map[string]string, attr string, gcpList []string) string { 265 num, err := strconv.Atoi(attributes[attr+".#"]) 266 if err != nil { 267 return fmt.Sprintf("Error in number conversion for attribute %s: %s", attr, err) 268 } 269 if num != len(gcpList) { 270 return fmt.Sprintf("Cluster has mismatched %s size.\nTF Size: %d\nGCP Size: %d", attr, num, len(gcpList)) 271 } 272 273 for i, gcp := range gcpList { 274 if tf := attributes[fmt.Sprintf("%s.%d", attr, i)]; tf != gcp { 275 return matchError(fmt.Sprintf("%s[%d]", attr, i), tf, gcp) 276 } 277 } 278 279 return "" 280 } 281 282 func matchError(attr, tf string, gcp interface{}) string { 283 return fmt.Sprintf("Cluster has mismatched %s.\nTF State: %+v\nGCP State: %+v", attr, tf, gcp) 284 } 285 286 var testAccContainerCluster_basic = fmt.Sprintf(` 287 resource "google_container_cluster" "primary" { 288 name = "cluster-test-%s" 289 zone = "us-central1-a" 290 initial_node_count = 3 291 292 master_auth { 293 username = "mr.yoda" 294 password = "adoy.rm" 295 } 296 }`, acctest.RandString(10)) 297 298 var testAccContainerCluster_withAdditionalZones = fmt.Sprintf(` 299 resource "google_container_cluster" "with_additional_zones" { 300 name = "cluster-test-%s" 301 zone = "us-central1-a" 302 initial_node_count = 1 303 304 additional_zones = [ 305 "us-central1-b", 306 "us-central1-c" 307 ] 308 309 master_auth { 310 username = "mr.yoda" 311 password = "adoy.rm" 312 } 313 }`, acctest.RandString(10)) 314 315 var testAccContainerCluster_withVersion = fmt.Sprintf(` 316 resource "google_container_cluster" "with_version" { 317 name = "cluster-test-%s" 318 zone = "us-central1-a" 319 node_version = "1.5.2" 320 initial_node_count = 1 321 322 master_auth { 323 username = "mr.yoda" 324 password = "adoy.rm" 325 } 326 }`, acctest.RandString(10)) 327 328 var testAccContainerCluster_withNodeConfig = fmt.Sprintf(` 329 resource "google_container_cluster" "with_node_config" { 330 name = "cluster-test-%s" 331 zone = "us-central1-f" 332 initial_node_count = 1 333 334 master_auth { 335 username = "mr.yoda" 336 password = "adoy.rm" 337 } 338 339 node_config { 340 machine_type = "g1-small" 341 disk_size_gb = 15 342 oauth_scopes = [ 343 "https://www.googleapis.com/auth/compute", 344 "https://www.googleapis.com/auth/devstorage.read_only", 345 "https://www.googleapis.com/auth/logging.write", 346 "https://www.googleapis.com/auth/monitoring" 347 ] 348 } 349 }`, acctest.RandString(10)) 350 351 var testAccContainerCluster_withNodeConfigScopeAlias = fmt.Sprintf(` 352 resource "google_container_cluster" "with_node_config_scope_alias" { 353 name = "cluster-test-%s" 354 zone = "us-central1-f" 355 initial_node_count = 1 356 357 master_auth { 358 username = "mr.yoda" 359 password = "adoy.rm" 360 } 361 362 node_config { 363 machine_type = "g1-small" 364 disk_size_gb = 15 365 oauth_scopes = [ "compute-rw", "storage-ro", "logging-write", "monitoring" ] 366 } 367 }`, acctest.RandString(10)) 368 369 var testAccContainerCluster_networkRef = fmt.Sprintf(` 370 resource "google_compute_network" "container_network" { 371 name = "container-net-%s" 372 auto_create_subnetworks = true 373 } 374 375 resource "google_container_cluster" "with_net_ref_by_url" { 376 name = "cluster-test-%s" 377 zone = "us-central1-a" 378 initial_node_count = 1 379 380 master_auth { 381 username = "mr.yoda" 382 password = "adoy.rm" 383 } 384 385 network = "${google_compute_network.container_network.self_link}" 386 } 387 388 resource "google_container_cluster" "with_net_ref_by_name" { 389 name = "cluster-test-%s" 390 zone = "us-central1-a" 391 initial_node_count = 1 392 393 master_auth { 394 username = "mr.yoda" 395 password = "adoy.rm" 396 } 397 398 network = "${google_compute_network.container_network.name}" 399 }`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10)) 400 401 var testAccContainerCluster_backendRef = fmt.Sprintf(` 402 resource "google_compute_backend_service" "my-backend-service" { 403 name = "terraform-test-%s" 404 port_name = "http" 405 protocol = "HTTP" 406 407 backend { 408 group = "${element(google_container_cluster.primary.instance_group_urls, 1)}" 409 } 410 411 health_checks = ["${google_compute_http_health_check.default.self_link}"] 412 } 413 414 resource "google_compute_http_health_check" "default" { 415 name = "terraform-test-%s" 416 request_path = "/" 417 check_interval_sec = 1 418 timeout_sec = 1 419 } 420 421 resource "google_container_cluster" "primary" { 422 name = "terraform-test-%s" 423 zone = "us-central1-a" 424 initial_node_count = 3 425 426 additional_zones = [ 427 "us-central1-b", 428 "us-central1-c", 429 ] 430 431 master_auth { 432 username = "mr.yoda" 433 password = "adoy.rm" 434 } 435 436 node_config { 437 oauth_scopes = [ 438 "https://www.googleapis.com/auth/compute", 439 "https://www.googleapis.com/auth/devstorage.read_only", 440 "https://www.googleapis.com/auth/logging.write", 441 "https://www.googleapis.com/auth/monitoring", 442 ] 443 } 444 } 445 `, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10))