Skip to content

Commit 944a92f

Browse files
committed
CORE: Add boot volume attachments data source.
This also fixes boot volume and subnet tests to avoid hardcoding availability domains. This allows boot volumes to be filtered if you know either endpoint of the attachment (the instance ID or the boot volume ID).
1 parent 2ac63f8 commit 944a92f

File tree

8 files changed

+379
-34
lines changed

8 files changed

+379
-34
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
2+
# oci_core_boot_volume_attachments
3+
4+
## BootVolumeAttachment DataSource
5+
6+
Gets a list of boot_volume_attachments.
7+
8+
### List Operation
9+
Lists the boot volume attachments in the specified compartment. You can filter the
10+
list by specifying an instance OCID, boot volume OCID, or both.
11+
12+
The following arguments are supported:
13+
14+
* `availability_domain` - (Required) The name of the Availability Domain. Example: `Uocm:PHX-AD-1`
15+
* `boot_volume_id` - (Optional) The OCID of the boot volume.
16+
* `compartment_id` - (Required) The OCID of the compartment.
17+
* `instance_id` - (Optional) The OCID of the instance.
18+
19+
20+
The following attributes are exported:
21+
22+
* `boot_volume_attachments` - The list of boot_volume_attachments.
23+
24+
### Example Usage
25+
26+
```hcl
27+
data "oci_core_boot_volume_attachments" "test_boot_volume_attachments" {
28+
#Required
29+
availability_domain = "${var.boot_volume_attachment_availability_domain}"
30+
compartment_id = "${var.compartment_id}"
31+
32+
#Optional
33+
boot_volume_id = "${oci_core_boot_volume.test_boot_volume.id}"
34+
instance_id = "${oci_core_instance.test_instance.id}"
35+
}
36+
```
37+
### BootVolumeAttachment Reference
38+
39+
The following attributes are exported:
40+
41+
* `availability_domain` - The Availability Domain of an instance. Example: `Uocm:PHX-AD-1`
42+
* `boot_volume_id` - The OCID of the boot volume.
43+
* `compartment_id` - The OCID of the compartment.
44+
* `display_name` - A user-friendly name. Does not have to be unique, and it cannot be changed. Avoid entering confidential information. Example: `My boot volume`
45+
* `id` - The OCID of the boot volume attachment.
46+
* `instance_id` - The OCID of the instance the boot volume is attached to.
47+
* `state` - The current state of the boot volume attachment.
48+
* `time_created` - The date and time the boot volume was created, in the format defined by RFC3339. Example: `2016-08-25T21:10:29.600Z`

docs/core/boot_volumes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ The following attributes are exported:
2020

2121
### Example Usage
2222

23-
```
23+
```hcl
2424
data "oci_core_boot_volumes" "test_boot_volumes" {
2525
#Required
2626
availability_domain = "${var.boot_volume_availability_domain}"

docs/examples/compute/instance/datasources.tf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,12 @@
22
data "oci_identity_availability_domains" "ADs" {
33
compartment_id = "${var.tenancy_ocid}"
44
}
5+
6+
# Gets the boot volume attachments for each instance
7+
data "oci_core_boot_volume_attachments" "TFBootVolumeAttachments" {
8+
count = "${var.NumInstances}"
9+
availability_domain = "${oci_core_instance.TFInstance.availability_domain}"
10+
compartment_id = "${var.compartment_ocid}"
11+
12+
instance_id = "${oci_core_instance.TFInstance.*.id[count.index]}"
13+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
2+
3+
package provider
4+
5+
import (
6+
"fmt"
7+
"regexp"
8+
"testing"
9+
10+
"github.com/hashicorp/terraform/helper/resource"
11+
"github.com/hashicorp/terraform/terraform"
12+
)
13+
14+
const (
15+
BootVolumeAttachmentResourceConfig = BootVolumeAttachmentResourceDependencies + `
16+
17+
`
18+
19+
BootVolumeAttachmentResourceDependencies = BootVolumeResourceDependencies
20+
)
21+
22+
func TestCoreBootVolumeAttachmentResource_basic(t *testing.T) {
23+
provider := testAccProvider
24+
config := testProviderConfig()
25+
26+
compartmentId2 := getRequiredEnvSetting("compartment_id_for_update")
27+
compartmentIdVariableStr2 := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId2)
28+
29+
datasourceName := "data.oci_core_boot_volume_attachments.test_boot_volume_attachments"
30+
31+
resource.Test(t, resource.TestCase{
32+
Providers: map[string]terraform.ResourceProvider{
33+
"oci": provider,
34+
},
35+
Steps: []resource.TestStep{
36+
// verify datasource can retrieve a specific attachment using server-side filtering
37+
{
38+
Config: config + `
39+
data "oci_core_boot_volume_attachments" "test_boot_volume_attachments" {
40+
#Required
41+
availability_domain = "${oci_core_instance.test_instance.availability_domain}"
42+
compartment_id = "${var.compartment_id}"
43+
44+
#Optional
45+
boot_volume_id = "${oci_core_instance.test_instance.boot_volume_id}"
46+
instance_id = "${oci_core_instance.test_instance.id}"
47+
}
48+
` + compartmentIdVariableStr2 + BootVolumeAttachmentResourceConfig,
49+
Check: resource.ComposeTestCheckFunc(
50+
resource.TestCheckResourceAttrSet(datasourceName, "boot_volume_id"),
51+
resource.TestCheckResourceAttr(datasourceName, "compartment_id", compartmentId2),
52+
resource.TestCheckResourceAttrSet(datasourceName, "instance_id"),
53+
54+
resource.TestCheckResourceAttr(datasourceName, "boot_volume_attachments.#", "1"),
55+
resource.TestCheckResourceAttrSet(datasourceName, "boot_volume_attachments.0.availability_domain"),
56+
TestCheckResourceAttributesEqual(datasourceName, "boot_volume_attachments.0.boot_volume_id", "oci_core_instance.test_instance", "boot_volume_id"),
57+
resource.TestCheckResourceAttrSet(datasourceName, "boot_volume_attachments.0.compartment_id"),
58+
resource.TestCheckResourceAttrSet(datasourceName, "boot_volume_attachments.0.display_name"),
59+
resource.TestCheckResourceAttrSet(datasourceName, "boot_volume_attachments.0.id"),
60+
TestCheckResourceAttributesEqual(datasourceName, "boot_volume_attachments.0.instance_id", "oci_core_instance.test_instance", "id"),
61+
resource.TestCheckResourceAttrSet(datasourceName, "boot_volume_attachments.0.state"),
62+
resource.TestCheckResourceAttrSet(datasourceName, "boot_volume_attachments.0.time_created"),
63+
),
64+
},
65+
// verify datasource can retrieve all boot volume attachments in a compartment by specifying no filtering options
66+
{
67+
Config: config + `
68+
data "oci_core_boot_volume_attachments" "test_boot_volume_attachments" {
69+
#Required
70+
availability_domain = "${oci_core_instance.test_instance.availability_domain}"
71+
compartment_id = "${var.compartment_id}"
72+
}
73+
` + compartmentIdVariableStr2 + BootVolumeAttachmentResourceConfig,
74+
Check: resource.ComposeTestCheckFunc(
75+
resource.TestCheckResourceAttr(datasourceName, "compartment_id", compartmentId2),
76+
resource.TestMatchResourceAttr(datasourceName, "boot_volume_attachments.#", regexp.MustCompile("[1-9][0-9]*")),
77+
),
78+
},
79+
},
80+
})
81+
}
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
// Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
2+
3+
package provider
4+
5+
import (
6+
"context"
7+
8+
"github.com/hashicorp/terraform/helper/schema"
9+
oci_core "github.com/oracle/oci-go-sdk/core"
10+
11+
"github.com/oracle/terraform-provider-oci/crud"
12+
)
13+
14+
func BootVolumeAttachmentsDataSource() *schema.Resource {
15+
return &schema.Resource{
16+
Read: readBootVolumeAttachments,
17+
Schema: map[string]*schema.Schema{
18+
"filter": dataSourceFiltersSchema(),
19+
"availability_domain": {
20+
Type: schema.TypeString,
21+
Required: true,
22+
},
23+
"boot_volume_id": {
24+
Type: schema.TypeString,
25+
Optional: true,
26+
},
27+
"compartment_id": {
28+
Type: schema.TypeString,
29+
Required: true,
30+
},
31+
"instance_id": {
32+
Type: schema.TypeString,
33+
Optional: true,
34+
},
35+
"boot_volume_attachments": {
36+
Type: schema.TypeList,
37+
Computed: true,
38+
Elem: &schema.Resource{
39+
Schema: map[string]*schema.Schema{
40+
// Required
41+
"boot_volume_id": {
42+
Type: schema.TypeString,
43+
Required: true,
44+
ForceNew: true,
45+
},
46+
"instance_id": {
47+
Type: schema.TypeString,
48+
Required: true,
49+
ForceNew: true,
50+
},
51+
52+
// Optional
53+
"display_name": {
54+
Type: schema.TypeString,
55+
Optional: true,
56+
Computed: true,
57+
ForceNew: true,
58+
},
59+
60+
// Computed
61+
"availability_domain": {
62+
Type: schema.TypeString,
63+
Computed: true,
64+
},
65+
"compartment_id": {
66+
Type: schema.TypeString,
67+
Computed: true,
68+
},
69+
"id": {
70+
Type: schema.TypeString,
71+
Computed: true,
72+
},
73+
"state": {
74+
Type: schema.TypeString,
75+
Computed: true,
76+
},
77+
"time_created": {
78+
Type: schema.TypeString,
79+
Computed: true,
80+
},
81+
},
82+
},
83+
},
84+
},
85+
}
86+
}
87+
88+
func readBootVolumeAttachments(d *schema.ResourceData, m interface{}) error {
89+
sync := &BootVolumeAttachmentsDataSourceCrud{}
90+
sync.D = d
91+
sync.Client = m.(*OracleClients).computeClient
92+
93+
return crud.ReadResource(sync)
94+
}
95+
96+
type BootVolumeAttachmentsDataSourceCrud struct {
97+
D *schema.ResourceData
98+
Client *oci_core.ComputeClient
99+
Res *oci_core.ListBootVolumeAttachmentsResponse
100+
}
101+
102+
func (s *BootVolumeAttachmentsDataSourceCrud) VoidState() {
103+
s.D.SetId("")
104+
}
105+
106+
func (s *BootVolumeAttachmentsDataSourceCrud) Get() error {
107+
request := oci_core.ListBootVolumeAttachmentsRequest{}
108+
109+
if availabilityDomain, ok := s.D.GetOkExists("availability_domain"); ok {
110+
tmp := availabilityDomain.(string)
111+
request.AvailabilityDomain = &tmp
112+
}
113+
114+
if bootVolumeId, ok := s.D.GetOkExists("boot_volume_id"); ok {
115+
tmp := bootVolumeId.(string)
116+
request.BootVolumeId = &tmp
117+
}
118+
119+
if compartmentId, ok := s.D.GetOkExists("compartment_id"); ok {
120+
tmp := compartmentId.(string)
121+
request.CompartmentId = &tmp
122+
}
123+
124+
if instanceId, ok := s.D.GetOkExists("instance_id"); ok {
125+
tmp := instanceId.(string)
126+
request.InstanceId = &tmp
127+
}
128+
129+
request.RequestMetadata.RetryPolicy = getRetryPolicy(false, "core")
130+
131+
response, err := s.Client.ListBootVolumeAttachments(context.Background(), request)
132+
if err != nil {
133+
return err
134+
}
135+
136+
s.Res = &response
137+
request.Page = s.Res.OpcNextPage
138+
139+
for request.Page != nil {
140+
listResponse, err := s.Client.ListBootVolumeAttachments(context.Background(), request)
141+
if err != nil {
142+
return err
143+
}
144+
145+
s.Res.Items = append(s.Res.Items, listResponse.Items...)
146+
request.Page = listResponse.OpcNextPage
147+
}
148+
149+
return nil
150+
}
151+
152+
func (s *BootVolumeAttachmentsDataSourceCrud) SetData() {
153+
if s.Res == nil {
154+
return
155+
}
156+
157+
s.D.SetId(crud.GenerateDataSourceID())
158+
resources := []map[string]interface{}{}
159+
160+
for _, r := range s.Res.Items {
161+
bootVolumeAttachment := map[string]interface{}{
162+
"availability_domain": *r.AvailabilityDomain,
163+
"compartment_id": *r.CompartmentId,
164+
}
165+
166+
if r.BootVolumeId != nil {
167+
bootVolumeAttachment["boot_volume_id"] = *r.BootVolumeId
168+
}
169+
170+
if r.DisplayName != nil {
171+
bootVolumeAttachment["display_name"] = *r.DisplayName
172+
}
173+
174+
if r.Id != nil {
175+
bootVolumeAttachment["id"] = *r.Id
176+
}
177+
178+
if r.InstanceId != nil {
179+
bootVolumeAttachment["instance_id"] = *r.InstanceId
180+
}
181+
182+
bootVolumeAttachment["state"] = r.LifecycleState
183+
184+
bootVolumeAttachment["time_created"] = r.TimeCreated.String()
185+
186+
resources = append(resources, bootVolumeAttachment)
187+
}
188+
189+
if f, fOk := s.D.GetOkExists("filter"); fOk {
190+
resources = ApplyFilters(f.(*schema.Set), resources)
191+
}
192+
193+
if err := s.D.Set("boot_volume_attachments", resources); err != nil {
194+
panic(err)
195+
}
196+
197+
return
198+
}

provider/core_boot_volume_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ variable "InstanceImageOCID" {
2929
`
3030
InstanceResourceConfigs = `
3131
resource "oci_core_instance" "test_instance" {
32-
availability_domain = "${var.subnet_availability_domain}"
32+
availability_domain = "${oci_core_subnet.test_subnet.availability_domain}"
3333
compartment_id = "${var.compartment_id}"
3434
display_name = "-tf-instance"
3535
image = "${var.InstanceImageOCID[var.region]}"
@@ -43,6 +43,7 @@ resource "oci_core_instance" "test_instance" {
4343
create = "15m"
4444
}
4545
}`
46+
4647
BootVolumeResourceDependencies = BootVolumePropertyVariables + SubnetPropertyVariables + SubnetRequiredOnlyResource + InstanceResourceConfigs
4748
)
4849

@@ -64,7 +65,7 @@ func TestCoreBootVolumeResource_basic(t *testing.T) {
6465
Config: config + BootVolumeResourceConfig + `
6566
data "oci_core_boot_volumes" "test_boot_volumes" {
6667
#Required
67-
availability_domain = "${var.subnet_availability_domain}"
68+
availability_domain = "${oci_core_instance.test_instance.availability_domain}"
6869
compartment_id = "${var.compartment_id}"
6970
7071
}

0 commit comments

Comments
 (0)