forked from heroku/terraform-provider-heroku
/
resource_heroku_space_peering_connection_accepter.go
151 lines (117 loc) · 4.01 KB
/
resource_heroku_space_peering_connection_accepter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package heroku
import (
"context"
"fmt"
"log"
"time"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/heroku/heroku-go/v3"
)
type spacePeerInfo struct {
heroku.Peering
}
func resourceHerokuSpacePeeringConnectionAccepter() *schema.Resource {
return &schema.Resource{
Create: resourceHerokuSpacePeeringConnectionAccepterCreate,
Read: resourceHerokuSpacePeeringConnectionAccepterRead,
Delete: resourceHerokuSpacePeeringConnectionAccepterDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"space": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"vpc_peering_connection_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
}
}
func resourceHerokuSpacePeeringConnectionAccepterCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Config).Api
spaceIdentity := d.Get("space").(string)
pcxID := d.Get("vpc_peering_connection_id").(string)
// There is a lag between when a peering request is initiated from AWS's end and when it
// appears as an option in a space's list of peering connections. In testing, this is
// usually in the 1-3 minute range. We retry for 5 minutes so plan/apply runs that
// create the two resources at the same time don't result in an error.
retryError := resource.Retry(5*time.Minute, func() *resource.RetryError {
_, err := client.PeeringAccept(context.TODO(), spaceIdentity, pcxID)
if err != nil {
return resource.RetryableError(err)
}
log.Printf("[INFO] Peer connection %s to %s has been accepted", pcxID, spaceIdentity)
return nil
})
if retryError != nil {
return fmt.Errorf("[ERROR] Unable to accept peer connection %s to %s", pcxID, spaceIdentity)
}
log.Printf("[INFO] Space ID: %s, Peering Connection ID: %s", spaceIdentity, pcxID)
d.SetId(pcxID)
log.Printf("[DEBUG] Waiting for connection (%s) to be accepted", d.Id())
stateConf := &resource.StateChangeConf{
Pending: []string{"initiating-request", "pending", "pending-acceptance", "provisioning"},
Target: []string{"active"},
Refresh: SpacePeeringConnAccepterStateRefreshFunc(client, spaceIdentity, d.Id()),
Timeout: 20 * time.Minute,
}
finalPeerConn, err := stateConf.WaitForState()
if err != nil {
return fmt.Errorf("Error waiting for Space (%s) to become available: %s", d.Id(), err)
}
p := finalPeerConn.(*spacePeerInfo)
d.Set("status", p.Status)
d.Set("type", p.Type)
return nil
}
func resourceHerokuSpacePeeringConnectionAccepterRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Config).Api
spaceIdentity := d.Get("space").(string)
peeringConn, err := client.PeeringInfo(context.TODO(), spaceIdentity, d.Id())
if err != nil {
return err
}
d.SetId(peeringConn.PcxID)
d.Set("status", peeringConn.Status)
d.Set("type", peeringConn.Type)
d.Set("vpc_peering_connection_id", peeringConn.PcxID)
return nil
}
func resourceHerokuSpacePeeringConnectionAccepterDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Config).Api
log.Printf("[INFO] Deleting space peering connection: %s", d.Id())
_, err := client.PeeringDestroy(context.TODO(), d.Get("space").(string), d.Id())
if err != nil {
return err
}
d.SetId("")
return nil
}
// SpaceStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
// a Space peering connection. Connections go through a provisioning process.
func SpacePeeringConnAccepterStateRefreshFunc(client *heroku.Service, spaceIdentity string, pcxID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
peeringConn, err := client.PeeringInfo(context.TODO(), spaceIdentity, pcxID)
if err != nil {
return nil, "", err
}
pcx := spacePeerInfo{
Peering: *peeringConn,
}
return &pcx, peeringConn.Status, nil
}
}