From d7dd7abf06189183429f52d3cb5e3c32319b6ec3 Mon Sep 17 00:00:00 2001 From: LBGarber Date: Tue, 20 Jul 2021 15:09:35 -0400 Subject: [PATCH] Fix shuffled node pool diffing --- linode/resource_linode_lke_cluster.go | 39 ++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/linode/resource_linode_lke_cluster.go b/linode/resource_linode_lke_cluster.go index 00ff976ea..1f236d464 100644 --- a/linode/resource_linode_lke_cluster.go +++ b/linode/resource_linode_lke_cluster.go @@ -140,6 +140,11 @@ func resourceLinodeLKEClusterRead(ctx context.Context, d *schema.ResourceData, m return diag.Errorf("Error parsing Linode LKE Cluster ID: %s", err) } + declaredPools, ok := d.Get("pool").([]interface{}) + if !ok { + return diag.Errorf("failed to parse linode lke cluster pools: %d", id) + } + cluster, err := client.GetLKECluster(context.Background(), id) if err != nil { if lerr, ok := err.(*linodego.Error); ok && lerr.Code == 404 { @@ -171,8 +176,9 @@ func resourceLinodeLKEClusterRead(ctx context.Context, d *schema.ResourceData, m d.Set("tags", cluster.Tags) d.Set("status", cluster.Status) d.Set("kubeconfig", kubeconfig.KubeConfig) - d.Set("pool", flattenLinodeLKEClusterPools(pools)) d.Set("api_endpoints", flattenLinodeLKEClusterAPIEndpoints(endpoints)) + d.Set("pool", flattenLinodeLKEClusterPools(matchPoolsWithSchema(pools, declaredPools))) + return nil } @@ -604,3 +610,34 @@ func flattenLinodeLKEClusterAPIEndpoints(apiEndpoints []linodego.LKEClusterAPIEn } return flattened } + +// This cannot currently be handled efficiently by a DiffSuppressFunc +// See: https://github.com/hashicorp/terraform-plugin-sdk/issues/477 +func matchPoolsWithSchema(pools []linodego.LKEClusterPool, declaredPools []interface{}) []linodego.LKEClusterPool { + result := make([]linodego.LKEClusterPool, len(declaredPools)) + + poolMap := make(map[int]linodego.LKEClusterPool, len(declaredPools)) + for _, pool := range pools { + poolMap[pool.ID] = pool + } + + for i, declaredPool := range declaredPools { + declaredPool := declaredPool.(map[string]interface{}) + + for key, pool := range poolMap { + if pool.Count != declaredPool["count"] || pool.Type != declaredPool["type"] { + continue + } + + result[i] = pool + delete(poolMap, key) + break + } + } + + for _, pool := range poolMap { + result = append(result, pool) + } + + return result +}