Skip to content

Commit 1486397

Browse files
authored
Add support for block volume fast clones (#347)
* Support creating clones from a running instance or a volume backup
1 parent f7f7362 commit 1486397

File tree

10 files changed

+171
-20
lines changed

10 files changed

+171
-20
lines changed

data_source_obmcs_core_volumes.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ func (s *VolumeDatasourceCrud) SetData() {
103103
"state": v.State,
104104
"time_created": v.TimeCreated.String(),
105105
}
106+
107+
if vsdRaw := v.VolumeSourceDetails; vsdRaw != nil {
108+
vsd := make(map[string]interface{})
109+
vsd["id"] = vsdRaw.Id
110+
vsd["type"] = vsdRaw.Type
111+
vol["source_details"] = []interface{}{vsd}
112+
}
113+
106114
resources = append(resources, vol)
107115
}
108116

data_source_obmcs_core_volumes_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ func (s *DatasourceCoreVolumeTestSuite) SetupTest() {
3434
compartment_id = "${var.compartment_id}"
3535
display_name = "-tf-volume"
3636
size_in_gbs = 50
37+
}
38+
39+
resource "oci_core_volume" "u" {
40+
availability_domain = "${data.oci_identity_availability_domains.ADs.availability_domains.0.name}"
41+
compartment_id = "${var.compartment_id}"
42+
display_name = "-tf-volume-clone"
43+
size_in_gbs = 50
44+
source_details {
45+
type = "volume"
46+
id = "${oci_core_volume.t.id}"
47+
}
3748
}`
3849
s.ResourceName = "data.oci_core_volumes.t"
3950
}
@@ -82,6 +93,22 @@ func (s *DatasourceCoreVolumeTestSuite) TestAccDatasourceCoreVolume_basic() {
8293
resource.TestCheckResourceAttr(s.ResourceName, "volumes.0.size_in_mbs", "51200"),
8394
),
8495
},
96+
{
97+
Config: s.Config + `
98+
data "oci_core_volumes" "u" {
99+
availability_domain = "${data.oci_identity_availability_domains.ADs.availability_domains.0.name}"
100+
compartment_id = "${oci_core_volume.u.compartment_id}"
101+
filter {
102+
name = "id"
103+
values = ["${oci_core_volume.u.id}"]
104+
}
105+
}`,
106+
Check: resource.ComposeTestCheckFunc(
107+
resource.TestCheckResourceAttr("data.oci_core_volumes.u", "volumes.#", "1"),
108+
resource.TestCheckResourceAttr("data.oci_core_volumes.u", "volumes.0.source_details.0.type", "volume"),
109+
resource.TestCheckResourceAttrSet("data.oci_core_volumes.u", "volumes.0.source_details.0.id"),
110+
),
111+
},
85112
},
86113
},
87114
)

docs/datasources/core/volumes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,4 @@ The following attributes are exported:
3838
* `state` - The current state of the volume. Allowed values are: [PROVISIONING, RESTORING, AVAILABLE, TERMINATING, TERMINATED, FAULTY]
3939
* `size_in_gbs` - The size of the volume, in GBs. The size must be a multiple of 1024.
4040
* `time_created` - The date and time the Volume was created, in the format defined by RFC3339. Example: `2016-08-25T21:10:29.600Z`.
41+
* `source_details` - Specifies the volume source details for a new Block Volume.

docs/resources/core/volume.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
# oci\_core\_volumes
22

3-
Gets a list of volumes in a compartment.
3+
Create a volume.
44

55
## Example Usage
66

77
```
88
resource "oci_core_volume" "t" {
99
availability_domain = "availability_domain"
1010
compartment_id = "compartment_id"
11-
size_in_gbs = 50
1211
volume_backup_id = "volume_id"
12+
size_in_gbs = 50
1313
}
1414
```
1515

@@ -21,6 +21,27 @@ The following arguments are supported:
2121
* `compartment_id` - (Required) The OCID of the compartment.
2222
* `display_name` - (Optional) A user-friendly name. Does not have to be unique, and it's changeable.
2323
* `volume_backup_id` - (Optional) The OCID of the volume backup from which the data should be restored on the newly created volume.
24+
* `source_details` - (Optional) Specifies the volume source details for a new Block Volume.
25+
See [Source Details](https://docs.us-phoenix-1.oraclecloud.com/api/#/en/iaas/20160918/requests/CreateVolumeDetails) documentation.
26+
Example usage:
27+
```
28+
resource "oci_core_volume" "t" {
29+
30+
source_details {
31+
type = "volume"
32+
id = "${var.volume_id}"
33+
}
34+
35+
// or
36+
37+
source_details {
38+
type = "volumeBackup"
39+
id = "${var.volume_backup_id}" // note: this requires an oci_core_volume_backup resource OCID
40+
}
41+
...
42+
}
43+
```
44+
2445

2546
## Attributes Reference
2647
* `availability_domain` - The availability domain of the volume.
@@ -31,3 +52,4 @@ The following arguments are supported:
3152
* `size_in_mbs` - (Deprecated) The size of the volume, in MBs.
3253
* `size_in_gbs` - The size of the volume, in GBs.
3354
* `time_created` - The date and time the Volume was created.
55+
* `source_details` - Specifies the volume source details for a new Block Volume.

resource_obmcs_core_volume.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,27 @@ func VolumeResource() *schema.Resource {
6767
Type: schema.TypeString,
6868
Computed: true,
6969
},
70+
"source_details": {
71+
Type: schema.TypeList,
72+
Optional: true,
73+
ForceNew: true,
74+
MaxItems: 1,
75+
MinItems: 1,
76+
Elem: &schema.Resource{
77+
Schema: map[string]*schema.Schema{
78+
"id": {
79+
Type: schema.TypeString,
80+
Required: true,
81+
ForceNew: true,
82+
},
83+
"type": {
84+
Type: schema.TypeString,
85+
Required: true,
86+
ForceNew: true,
87+
},
88+
},
89+
},
90+
},
7091
},
7192
}
7293
}
@@ -159,6 +180,15 @@ func (s *VolumeResourceCrud) Create() (e error) {
159180
opts.VolumeBackupID = volumeBackupID.(string)
160181
}
161182

183+
if sourceDetailsList, listOk := s.D.GetOk("source_details"); listOk {
184+
sourceDetailsItem := sourceDetailsList.([]interface{})[0] // if listOk this is assured to have exactly 1 item
185+
sdItem := sourceDetailsItem.(map[string]interface{})
186+
opts.VolumeSourceDetails = &baremetal.VolumeSourceDetails{
187+
sdItem["id"].(string),
188+
sdItem["type"].(string),
189+
}
190+
}
191+
162192
s.Res, e = s.Client.CreateVolume(availabilityDomain, compartmentID, opts)
163193

164194
return
@@ -192,6 +222,13 @@ func (s *VolumeResourceCrud) SetData() {
192222
s.D.Set("size_in_gbs", s.Res.SizeInGBs)
193223
s.D.Set("state", s.Res.State)
194224
s.D.Set("time_created", s.Res.TimeCreated.String())
225+
226+
if vsdRaw := s.Res.VolumeSourceDetails; vsdRaw != nil {
227+
vsd := make(map[string]interface{})
228+
vsd["id"] = vsdRaw.Id
229+
vsd["type"] = vsdRaw.Type
230+
s.D.Set("source_details", vsd)
231+
}
195232
}
196233

197234
func (s *VolumeResourceCrud) Delete() (e error) {

resource_obmcs_core_volume_backup_test.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func (s *ResourceCoreVolumeBackupTestSuite) TestAccResourceCoreVolumeBackup_basi
7575
resource.TestCheckResourceAttr(s.ResourceName, "display_name", "-tf-volume-backup"),
7676
),
7777
},
78-
// verify restore
78+
// verify conventional restore
7979
{
8080
Config: s.Config + `
8181
resource "oci_core_volume_backup" "t" {
@@ -93,6 +93,30 @@ func (s *ResourceCoreVolumeBackupTestSuite) TestAccResourceCoreVolumeBackup_basi
9393
resource.TestCheckResourceAttr("oci_core_volume.t2", "display_name", "-tf-volume-restored"),
9494
),
9595
},
96+
// verify clone from backup
97+
{
98+
Config: s.Config + `
99+
resource "oci_core_volume_backup" "t" {
100+
volume_id = "${oci_core_volume.t.id}"
101+
display_name = "-tf-volume-backup"
102+
}
103+
resource "oci_core_volume" "u" {
104+
availability_domain = "${data.oci_identity_availability_domains.ADs.availability_domains.0.name}"
105+
compartment_id = "${var.compartment_id}"
106+
display_name = "-tf-volume-clone"
107+
size_in_gbs = 50
108+
source_details {
109+
type = "volumeBackup"
110+
id = "${oci_core_volume_backup.t.id}"
111+
}
112+
}`,
113+
Check: resource.ComposeTestCheckFunc(
114+
resource.TestCheckResourceAttrSet("oci_core_volume.u", "source_details.0.id"),
115+
resource.TestCheckResourceAttr("oci_core_volume.u", "display_name", "-tf-volume-clone"),
116+
resource.TestCheckResourceAttr("oci_core_volume.u", "source_details.0.type", "volumeBackup"),
117+
resource.TestCheckResourceAttr("oci_core_volume.u", "state", baremetal.ResourceAvailable),
118+
),
119+
},
96120
},
97121
})
98122
}

resource_obmcs_core_volume_test.go

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
package main
44

55
import (
6+
"testing"
7+
68
"fmt"
79
"regexp"
8-
"testing"
910

1011
"github.com/hashicorp/terraform/helper/resource"
1112
"github.com/hashicorp/terraform/terraform"
@@ -20,8 +21,6 @@ type ResourceCoreVolumeTestSuite struct {
2021
Providers map[string]terraform.ResourceProvider
2122
Config string
2223
ResourceName string
23-
Res *baremetal.Volume
24-
DeletedRes *baremetal.Volume
2524
}
2625

2726
func (s *ResourceCoreVolumeTestSuite) SetupTest() {
@@ -102,6 +101,32 @@ func (s *ResourceCoreVolumeTestSuite) TestCreateResourceCoreVolume_basic() {
102101
}`,
103102
ExpectNonEmptyPlan: false,
104103
},
104+
// create a clone off the existing volume
105+
{
106+
Config: s.Config + `
107+
resource "oci_core_volume" "t" {
108+
availability_domain = "${data.oci_identity_availability_domains.ADs.availability_domains.0.name}"
109+
compartment_id = "${var.compartment_id}"
110+
display_name = "-tf-volume"
111+
size_in_gbs = 50
112+
}
113+
resource "oci_core_volume" "u" {
114+
availability_domain = "${data.oci_identity_availability_domains.ADs.availability_domains.0.name}"
115+
compartment_id = "${var.compartment_id}"
116+
display_name = "-tf-volume-clone"
117+
size_in_gbs = 50
118+
source_details {
119+
type = "volume"
120+
id = "${oci_core_volume.t.id}"
121+
}
122+
}`,
123+
Check: resource.ComposeTestCheckFunc(
124+
resource.TestCheckResourceAttrSet("oci_core_volume.u", "source_details.0.id"),
125+
resource.TestCheckResourceAttr("oci_core_volume.u", "display_name", "-tf-volume-clone"),
126+
resource.TestCheckResourceAttr("oci_core_volume.u", "source_details.0.type", "volume"),
127+
resource.TestCheckResourceAttr("oci_core_volume.u", "state", baremetal.ResourceAvailable),
128+
),
129+
},
105130
},
106131
})
107132
}

vendor/github.com/oracle/bmcs-go-sdk/core_volume.go

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

vendor/github.com/oracle/bmcs-go-sdk/request_options.go

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

vendor/vendor.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,10 +2972,10 @@
29722972
"revisionTime": "2017-01-25T16:36:56Z"
29732973
},
29742974
{
2975-
"checksumSHA1": "Swv3Qr8tQWyEN9KlAYC6eyD1J8E=",
2975+
"checksumSHA1": "FZuTNT1Cksd4WxwAFXS42LvbOtA=",
29762976
"path": "github.com/oracle/bmcs-go-sdk",
2977-
"revision": "b4d4e32d4024fff11c732f5e3721c86c418b35ff",
2978-
"revisionTime": "2017-10-20T22:37:45Z",
2977+
"revision": "79eba688b52b26d9b38e71860e69cd671fed7979",
2978+
"revisionTime": "2017-11-01T22:20:57Z",
29792979
"version": "add-db-license-model",
29802980
"versionExact": "add-db-license-model"
29812981
},

0 commit comments

Comments
 (0)