github.com/Kevinklinger/open_terraform@v0.11.12-beta1/builtin/providers/test/resource_with_custom_diff.go (about) 1 package test 2 3 import ( 4 "fmt" 5 6 "github.com/hashicorp/terraform/helper/schema" 7 ) 8 9 func testResourceCustomDiff() *schema.Resource { 10 return &schema.Resource{ 11 Create: testResourceCustomDiffCreate, 12 Read: testResourceCustomDiffRead, 13 CustomizeDiff: testResourceCustomDiffCustomizeDiff, 14 Update: testResourceCustomDiffUpdate, 15 Delete: testResourceCustomDiffDelete, 16 Schema: map[string]*schema.Schema{ 17 "required": { 18 Type: schema.TypeString, 19 Required: true, 20 }, 21 "computed": { 22 Type: schema.TypeInt, 23 Computed: true, 24 }, 25 "index": { 26 Type: schema.TypeInt, 27 Computed: true, 28 }, 29 "veto": { 30 Type: schema.TypeBool, 31 Optional: true, 32 }, 33 "list": { 34 Type: schema.TypeList, 35 Computed: true, 36 Elem: &schema.Schema{Type: schema.TypeString}, 37 }, 38 }, 39 } 40 } 41 42 type listDiffCases struct { 43 Type string 44 Value string 45 } 46 47 func testListDiffCases(index int) []listDiffCases { 48 switch index { 49 case 0: 50 return []listDiffCases{ 51 { 52 Type: "add", 53 Value: "dc1", 54 }, 55 } 56 case 1: 57 return []listDiffCases{ 58 { 59 Type: "remove", 60 Value: "dc1", 61 }, 62 { 63 Type: "add", 64 Value: "dc2", 65 }, 66 { 67 Type: "add", 68 Value: "dc3", 69 }, 70 } 71 } 72 return nil 73 } 74 75 func testListDiffCasesReadResult(index int) []interface{} { 76 switch index { 77 case 1: 78 return []interface{}{"dc1"} 79 default: 80 return []interface{}{"dc2", "dc3"} 81 } 82 } 83 84 func testResourceCustomDiffCreate(d *schema.ResourceData, meta interface{}) error { 85 d.SetId("testId") 86 87 // Required must make it through to Create 88 if _, ok := d.GetOk("required"); !ok { 89 return fmt.Errorf("missing attribute 'required', but it's required") 90 } 91 92 _, new := d.GetChange("computed") 93 expected := new.(int) - 1 94 actual := d.Get("index").(int) 95 if expected != actual { 96 return fmt.Errorf("expected computed to be 1 ahead of index, got computed: %d, index: %d", expected, actual) 97 } 98 d.Set("index", new) 99 100 return testResourceCustomDiffRead(d, meta) 101 } 102 103 func testResourceCustomDiffRead(d *schema.ResourceData, meta interface{}) error { 104 if err := d.Set("list", testListDiffCasesReadResult(d.Get("index").(int))); err != nil { 105 return err 106 } 107 return nil 108 } 109 110 func testResourceCustomDiffCustomizeDiff(d *schema.ResourceDiff, meta interface{}) error { 111 if d.Get("veto").(bool) == true { 112 return fmt.Errorf("veto is true, diff vetoed") 113 } 114 // Note that this gets put into state after the update, regardless of whether 115 // or not anything is acted upon in the diff. 116 d.SetNew("computed", d.Get("computed").(int)+1) 117 118 // This tests a diffed list, based off of the value of index 119 dcs := testListDiffCases(d.Get("index").(int)) 120 s := d.Get("list").([]interface{}) 121 for _, dc := range dcs { 122 switch dc.Type { 123 case "add": 124 s = append(s, dc.Value) 125 case "remove": 126 for i := range s { 127 if s[i].(string) == dc.Value { 128 copy(s[i:], s[i+1:]) 129 s = s[:len(s)-1] 130 break 131 } 132 } 133 } 134 } 135 d.SetNew("list", s) 136 137 return nil 138 } 139 140 func testResourceCustomDiffUpdate(d *schema.ResourceData, meta interface{}) error { 141 _, new := d.GetChange("computed") 142 expected := new.(int) - 1 143 actual := d.Get("index").(int) 144 if expected != actual { 145 return fmt.Errorf("expected computed to be 1 ahead of index, got computed: %d, index: %d", expected, actual) 146 } 147 d.Set("index", new) 148 return testResourceCustomDiffRead(d, meta) 149 } 150 151 func testResourceCustomDiffDelete(d *schema.ResourceData, meta interface{}) error { 152 d.SetId("") 153 return nil 154 }