Skip to content

Commit 3099fc7

Browse files
committed
add volume
1 parent 3481d1b commit 3099fc7

18 files changed

Lines changed: 802 additions & 72 deletions

builtin/providers/packet/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func Provider() terraform.ResourceProvider {
2121
"packet_device": resourcePacketDevice(),
2222
"packet_ssh_key": resourcePacketSSHKey(),
2323
"packet_project": resourcePacketProject(),
24+
"packet_volume": resourcePacketVolume(),
2425
},
2526

2627
ConfigureFunc: providerConfigure,

builtin/providers/packet/resource_packet_device.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,13 @@ func resourcePacketDeviceRead(d *schema.ResourceData, meta interface{}) error {
208208
network := map[string]interface{}{
209209
"address": ip.Address,
210210
"gateway": ip.Gateway,
211-
"family": ip.Family,
211+
"family": ip.AddressFamily,
212212
"cidr": ip.Cidr,
213213
"public": ip.Public,
214214
}
215215
networks = append(networks, network)
216216

217-
if ip.Family == 4 && ip.Public == true {
217+
if ip.AddressFamily == 4 && ip.Public == true {
218218
host = ip.Address
219219
}
220220
}
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
package packet
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/hashicorp/terraform/helper/schema"
7+
"github.com/packethost/packngo"
8+
)
9+
10+
func resourcePacketVolume() *schema.Resource {
11+
return &schema.Resource{
12+
Create: resourcePacketVolumeCreate,
13+
Read: resourcePacketVolumeRead,
14+
Update: resourcePacketVolumeUpdate,
15+
Delete: resourcePacketVolumeDelete,
16+
17+
Schema: map[string]*schema.Schema{
18+
"project_id": &schema.Schema{
19+
Type: schema.TypeString,
20+
Required: true,
21+
ForceNew: true,
22+
},
23+
24+
"name": &schema.Schema{
25+
Type: schema.TypeString,
26+
Computed: true,
27+
},
28+
29+
"description": &schema.Schema{
30+
Type: schema.TypeString,
31+
Required: false,
32+
Optional: true,
33+
},
34+
35+
"size": &schema.Schema{
36+
Type: schema.TypeInt,
37+
Required: false,
38+
Optional: true,
39+
Computed: true,
40+
},
41+
42+
"facility": &schema.Schema{
43+
Type: schema.TypeString,
44+
Required: true,
45+
ForceNew: true,
46+
},
47+
48+
"plan": &schema.Schema{
49+
Type: schema.TypeString,
50+
Required: true,
51+
ForceNew: true,
52+
},
53+
54+
"billing_cycle": &schema.Schema{
55+
Type: schema.TypeString,
56+
Required: true,
57+
ForceNew: true,
58+
},
59+
60+
"state": &schema.Schema{
61+
Type: schema.TypeString,
62+
Computed: true,
63+
},
64+
65+
"locked": &schema.Schema{
66+
Type: schema.TypeBool,
67+
Computed: true,
68+
},
69+
70+
"snapshot_policies": &schema.Schema{
71+
Type: schema.TypeList,
72+
Optional: true,
73+
Elem: &schema.Resource{
74+
Schema: map[string]*schema.Schema{
75+
"snapshot_frequency": &schema.Schema{
76+
Type: schema.TypeString,
77+
Required: true,
78+
ForceNew: true,
79+
},
80+
"snapshot_count": &schema.Schema{
81+
Type: schema.TypeInt,
82+
Required: true,
83+
ForceNew: true,
84+
},
85+
},
86+
},
87+
},
88+
89+
"attachments": &schema.Schema{
90+
Type: schema.TypeList,
91+
Computed: true,
92+
Elem: &schema.Resource{
93+
Schema: map[string]*schema.Schema{
94+
"href": &schema.Schema{
95+
Type: schema.TypeString,
96+
Computed: true,
97+
},
98+
},
99+
},
100+
},
101+
102+
"created": &schema.Schema{
103+
Type: schema.TypeString,
104+
Computed: true,
105+
},
106+
107+
"updated": &schema.Schema{
108+
Type: schema.TypeString,
109+
Computed: true,
110+
},
111+
},
112+
}
113+
}
114+
115+
func resourcePacketVolumeCreate(d *schema.ResourceData, meta interface{}) error {
116+
client := meta.(*packngo.Client)
117+
118+
createRequest := &packngo.VolumeCreateRequest{
119+
PlanID: d.Get("plan").(string),
120+
FacilityID: d.Get("facility").(string),
121+
BillingCycle: d.Get("billing_cycle").(string),
122+
ProjectID: d.Get("project_id").(string),
123+
}
124+
125+
if attr, ok := d.GetOk("description"); ok {
126+
createRequest.Description = attr.(string)
127+
}
128+
129+
if attr, ok := d.GetOk("size"); ok {
130+
createRequest.Size = attr.(int)
131+
}
132+
133+
snapshot_policies := d.Get("snapshot_policies.#").(int)
134+
if snapshot_policies > 0 {
135+
createRequest.SnapshotPolicies = make([]*packngo.SnapshotPolicy, 0, snapshot_policies)
136+
for i := 0; i < snapshot_policies; i++ {
137+
key := fmt.Sprintf("snapshot_policies.%d", i)
138+
createRequest.SnapshotPolicies = append(createRequest.SnapshotPolicies, d.Get(key).(*packngo.SnapshotPolicy))
139+
}
140+
}
141+
142+
newVolume, _, err := client.Volumes.Create(createRequest)
143+
if err != nil {
144+
return friendlyError(err)
145+
}
146+
147+
d.SetId(newVolume.ID)
148+
149+
return resourcePacketVolumeRead(d, meta)
150+
}
151+
152+
func resourcePacketVolumeRead(d *schema.ResourceData, meta interface{}) error {
153+
client := meta.(*packngo.Client)
154+
155+
device, _, err := client.Volumes.Get(d.Id())
156+
if err != nil {
157+
err = friendlyError(err)
158+
159+
// If the volume somehow already destroyed, mark as succesfully gone.
160+
if isNotFound(err) {
161+
d.SetId("")
162+
return nil
163+
}
164+
165+
return err
166+
}
167+
168+
d.Set("name", device.Name)
169+
d.Set("description", device.Description)
170+
d.Set("size", device.Size)
171+
d.Set("plan", device.Plan.Slug)
172+
d.Set("facility", device.Facility.Code)
173+
d.Set("state", device.State)
174+
d.Set("billing_cycle", device.BillingCycle)
175+
d.Set("locked", device.Locked)
176+
d.Set("created", device.Created)
177+
d.Set("updated", device.Updated)
178+
179+
snapshot_policies := make([]*packngo.SnapshotPolicy, 0, len(device.SnapshotPolicies))
180+
for _, snapshot_policy := range device.SnapshotPolicies {
181+
snapshot_policies = append(snapshot_policies, snapshot_policy)
182+
}
183+
d.Set("snapshot_policies", snapshot_policies)
184+
185+
attachments := make([]*packngo.Attachment, 0, len(device.Attachments))
186+
for _, attachment := range device.Attachments {
187+
attachments = append(attachments, attachment)
188+
}
189+
d.Set("attachments", attachments)
190+
191+
return nil
192+
}
193+
194+
func resourcePacketVolumeUpdate(d *schema.ResourceData, meta interface{}) error {
195+
client := meta.(*packngo.Client)
196+
197+
updateRequest := &packngo.VolumeUpdateRequest{
198+
ID: d.Get("id").(string),
199+
}
200+
201+
if attr, ok := d.GetOk("description"); ok {
202+
updateRequest.Description = attr.(string)
203+
}
204+
205+
if attr, ok := d.GetOk("plan"); ok {
206+
updateRequest.Plan = attr.(string)
207+
}
208+
209+
_, _, err := client.Volumes.Update(updateRequest)
210+
if err != nil {
211+
return friendlyError(err)
212+
}
213+
214+
return resourcePacketVolumeRead(d, meta)
215+
}
216+
217+
func resourcePacketVolumeDelete(d *schema.ResourceData, meta interface{}) error {
218+
client := meta.(*packngo.Client)
219+
220+
if _, err := client.Volumes.Delete(d.Id()); err != nil {
221+
return friendlyError(err)
222+
}
223+
224+
return nil
225+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package packet
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform/helper/resource"
8+
"github.com/hashicorp/terraform/terraform"
9+
"github.com/packethost/packngo"
10+
)
11+
12+
func TestAccPacketVolume_Basic(t *testing.T) {
13+
var volume packngo.Volume
14+
15+
resource.Test(t, resource.TestCase{
16+
PreCheck: func() { testAccPreCheck(t) },
17+
Providers: testAccProviders,
18+
CheckDestroy: testAccCheckPacketVolumeDestroy,
19+
Steps: []resource.TestStep{
20+
resource.TestStep{
21+
Config: testAccCheckPacketVolumeConfig_basic,
22+
Check: resource.ComposeTestCheckFunc(
23+
testAccCheckPacketVolumeExists("packet_volume.foobar", &volume),
24+
testAccCheckPacketVolumeAttributes(&volume),
25+
resource.TestCheckResourceAttr(
26+
"packet_volume.foobar", "name", "foobar"),
27+
),
28+
},
29+
},
30+
})
31+
}
32+
33+
func testAccCheckPacketVolumeDestroy(s *terraform.State) error {
34+
client := testAccProvider.Meta().(*packngo.Client)
35+
36+
for _, rs := range s.RootModule().Resources {
37+
if rs.Type != "packet_volume" {
38+
continue
39+
}
40+
if _, _, err := client.Volumes.Get(rs.Primary.ID); err == nil {
41+
return fmt.Errorf("Volume cstill exists")
42+
}
43+
}
44+
45+
return nil
46+
}
47+
48+
func testAccCheckPacketVolumeAttributes(volume *packngo.Volume) resource.TestCheckFunc {
49+
return func(s *terraform.State) error {
50+
if volume.Name != "foobar" {
51+
return fmt.Errorf("Bad name: %s", volume.Name)
52+
}
53+
return nil
54+
}
55+
}
56+
57+
func testAccCheckPacketVolumeExists(n string, volume *packngo.Volume) resource.TestCheckFunc {
58+
return func(s *terraform.State) error {
59+
rs, ok := s.RootModule().Resources[n]
60+
if !ok {
61+
return fmt.Errorf("Not found: %s", n)
62+
}
63+
if rs.Primary.ID == "" {
64+
return fmt.Errorf("No Record ID is set")
65+
}
66+
67+
client := testAccProvider.Meta().(*packngo.Client)
68+
69+
foundVolume, _, err := client.Volumes.Get(rs.Primary.ID)
70+
if err != nil {
71+
return err
72+
}
73+
if foundVolume.ID != rs.Primary.ID {
74+
return fmt.Errorf("Record not found: %v - %v", rs.Primary.ID, foundVolume)
75+
}
76+
77+
*volume = *foundVolume
78+
79+
return nil
80+
}
81+
}
82+
83+
var testAccCheckPacketVolumeConfig_basic = fmt.Sprintf(`
84+
resource "packet_volume" "foobar" {
85+
name = "foobar"
86+
}`)

vendor/github.com/packethost/packngo/README.md

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/packethost/packngo/devices.go

Lines changed: 0 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/packethost/packngo/email.go

Lines changed: 6 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)