github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/google/resource_compute_firewall_migrate.go (about)

     1  package google
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"sort"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/hashicorp/terraform/terraform"
    11  )
    12  
    13  func resourceComputeFirewallMigrateState(
    14  	v int, is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) {
    15  	if is.Empty() {
    16  		log.Println("[DEBUG] Empty FirewallState; nothing to migrate.")
    17  		return is, nil
    18  	}
    19  
    20  	switch v {
    21  	case 0:
    22  		log.Println("[INFO] Found Compute Firewall State v0; migrating to v1")
    23  		is, err := migrateFirewallStateV0toV1(is)
    24  		if err != nil {
    25  			return is, err
    26  		}
    27  		return is, nil
    28  	default:
    29  		return is, fmt.Errorf("Unexpected schema version: %d", v)
    30  	}
    31  }
    32  
    33  func migrateFirewallStateV0toV1(is *terraform.InstanceState) (*terraform.InstanceState, error) {
    34  	log.Printf("[DEBUG] Attributes before migration: %#v", is.Attributes)
    35  	idx := 0
    36  	portCount := 0
    37  	newPorts := make(map[string]string)
    38  	keys := make([]string, len(is.Attributes))
    39  	for k, _ := range is.Attributes {
    40  		keys[idx] = k
    41  		idx++
    42  
    43  	}
    44  	sort.Strings(keys)
    45  	for _, k := range keys {
    46  		if !strings.HasPrefix(k, "allow.") {
    47  			continue
    48  		}
    49  
    50  		if k == "allow.#" {
    51  			continue
    52  		}
    53  
    54  		if strings.HasSuffix(k, ".ports.#") {
    55  			continue
    56  		}
    57  
    58  		if strings.HasSuffix(k, ".protocol") {
    59  			continue
    60  		}
    61  
    62  		// We have a key that looks like "allow.<hash>.ports.*" and we know it's not
    63  		// allow.<hash>.ports.# because we deleted it above, so it must be allow.<hash1>.ports.<hash2>
    64  		// from the Set of Ports. Just need to convert it to a list by
    65  		// replacing second hash with sequential numbers.
    66  		kParts := strings.Split(k, ".")
    67  
    68  		// Sanity check: all four parts should be there and <hash> should be a number
    69  		badFormat := false
    70  		if len(kParts) != 4 {
    71  			badFormat = true
    72  		} else if _, err := strconv.Atoi(kParts[1]); err != nil {
    73  			badFormat = true
    74  		}
    75  
    76  		if badFormat {
    77  			return is, fmt.Errorf(
    78  				"migration error: found port key in unexpected format: %s", k)
    79  		}
    80  		allowHash, _ := strconv.Atoi(kParts[1])
    81  		newK := fmt.Sprintf("allow.%d.ports.%d", allowHash, portCount)
    82  		portCount++
    83  		newPorts[newK] = is.Attributes[k]
    84  		delete(is.Attributes, k)
    85  	}
    86  
    87  	for k, v := range newPorts {
    88  		is.Attributes[k] = v
    89  	}
    90  
    91  	log.Printf("[DEBUG] Attributes after migration: %#v", is.Attributes)
    92  	return is, nil
    93  }