Skip to content

Commit 9f09841

Browse files
authored
Merge pull request #237 from oracle/privateIps
adding support for Secondary Private IPs
2 parents 7be1a4d + 755aa63 commit 9f09841

File tree

10 files changed

+764
-0
lines changed

10 files changed

+764
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
2+
3+
package main
4+
5+
import (
6+
"time"
7+
8+
"github.com/MustWin/baremetal-sdk-go"
9+
"github.com/hashicorp/terraform/helper/schema"
10+
"github.com/oracle/terraform-provider-oci/options"
11+
12+
"github.com/oracle/terraform-provider-oci/crud"
13+
)
14+
15+
func PrivateIPDatasource() *schema.Resource {
16+
return &schema.Resource{
17+
Read: readPrivateIPs,
18+
Schema: map[string]*schema.Schema{
19+
"ip_address": {
20+
Type: schema.TypeString,
21+
Optional: true,
22+
},
23+
"subnet_id": {
24+
Type: schema.TypeString,
25+
Optional: true,
26+
},
27+
"vnic_id": {
28+
Type: schema.TypeString,
29+
Optional: true,
30+
},
31+
32+
"private_ips": {
33+
Type: schema.TypeList,
34+
Computed: true,
35+
Elem: PrivateIPResource(),
36+
},
37+
},
38+
}
39+
}
40+
41+
func readPrivateIPs(d *schema.ResourceData, m interface{}) (e error) {
42+
client := m.(*baremetal.Client)
43+
sync := &PrivateIPDatasourceCrud{}
44+
sync.D = d
45+
sync.Client = client
46+
return crud.ReadResource(sync)
47+
}
48+
49+
type PrivateIPDatasourceCrud struct {
50+
crud.BaseCrud
51+
Res *baremetal.ListPrivateIPs
52+
}
53+
54+
func (s *PrivateIPDatasourceCrud) Get() (e error) {
55+
56+
opts := &baremetal.ListPrivateIPsOptions{}
57+
options.SetListOptions(s.D, &opts.ListOptions)
58+
if val, ok := s.D.GetOk("ip_address"); ok {
59+
opts.IPAddress = val.(string)
60+
}
61+
if val, ok := s.D.GetOk("subnet_id"); ok {
62+
opts.SubnetID = val.(string)
63+
}
64+
if val, ok := s.D.GetOk("vnic_id"); ok {
65+
opts.VnicID = val.(string)
66+
}
67+
68+
s.Res = &baremetal.ListPrivateIPs{PrivateIPs: []baremetal.PrivateIP{}}
69+
70+
for {
71+
var list *baremetal.ListPrivateIPs
72+
if list, e = s.Client.ListPrivateIPs(opts); e != nil {
73+
break
74+
}
75+
76+
s.Res.PrivateIPs = append(s.Res.PrivateIPs, list.PrivateIPs...)
77+
78+
if hasNextPage := options.SetNextPageOption(list.NextPage, &opts.PageListOptions); !hasNextPage {
79+
break
80+
}
81+
}
82+
return
83+
}
84+
85+
func (s *PrivateIPDatasourceCrud) SetData() {
86+
if s.Res != nil {
87+
s.D.SetId(time.Now().UTC().String())
88+
resources := []map[string]interface{}{}
89+
for _, r := range s.Res.PrivateIPs {
90+
res := map[string]interface{}{
91+
"availability_domain": r.AvailabilityDomain,
92+
"compartment_id": r.CompartmentID,
93+
"display_name": r.DisplayName,
94+
"hostname_label": r.HostnameLabel,
95+
"id": r.ID,
96+
"ip_address": r.IPAddress,
97+
"is_primary": r.IsPrimary,
98+
"subnet_id": r.SubnetID,
99+
"time_created": r.TimeCreated.String(),
100+
"vnic_id": r.VnicID,
101+
}
102+
resources = append(resources, res)
103+
}
104+
s.D.Set("private_ips", resources)
105+
}
106+
return
107+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
2+
3+
package main
4+
5+
import (
6+
"testing"
7+
8+
"github.com/MustWin/baremetal-sdk-go"
9+
"github.com/hashicorp/terraform/helper/resource"
10+
"github.com/hashicorp/terraform/helper/schema"
11+
"github.com/hashicorp/terraform/terraform"
12+
13+
"github.com/stretchr/testify/suite"
14+
)
15+
16+
type DatasourcePrivateIPTestSuite struct {
17+
suite.Suite
18+
Client *baremetal.Client
19+
Config string
20+
Provider terraform.ResourceProvider
21+
Providers map[string]terraform.ResourceProvider
22+
ResourceName string
23+
List *baremetal.ListPrivateIPs
24+
}
25+
26+
func (s *DatasourcePrivateIPTestSuite) SetupTest() {
27+
s.Client = GetTestProvider()
28+
s.Provider = Provider(func(d *schema.ResourceData) (interface{}, error) {
29+
return s.Client, nil
30+
})
31+
32+
s.Providers = map[string]terraform.ResourceProvider{
33+
"oci": s.Provider,
34+
}
35+
s.Config = vnicConfig + `
36+
resource "oci_core_private_ip" "testPrivateIP" {
37+
vnic_id = "${lookup(data.oci_core_vnic_attachments.vnics.vnic_attachments[0],"vnic_id")}"
38+
ip_address = "10.0.1.23"
39+
}
40+
`
41+
s.Config += testProviderConfig()
42+
s.ResourceName = "data.oci_core_private_ips.testPrivateIPs"
43+
}
44+
45+
func (s *DatasourcePrivateIPTestSuite) TestListPrivateIPsByVnicID() {
46+
47+
resource.UnitTest(s.T(), resource.TestCase{
48+
PreventPostDestroyRefresh: true,
49+
Providers: s.Providers,
50+
Steps: []resource.TestStep{
51+
{
52+
ImportState: true,
53+
ImportStateVerify: true,
54+
Config: s.Config,
55+
},
56+
{
57+
Config: s.Config + `
58+
data "oci_core_private_ips" "testPrivateIPs" {
59+
vnic_id = "${lookup(data.oci_core_vnic_attachments.vnics.vnic_attachments[0],"vnic_id")}"
60+
}
61+
`,
62+
Check: resource.ComposeTestCheckFunc(
63+
resource.TestCheckResourceAttr(s.ResourceName, "private_ips.#", "2"),
64+
resource.TestCheckResourceAttrSet(s.ResourceName, "private_ips.0.id"),
65+
resource.TestCheckResourceAttrSet(s.ResourceName, "private_ips.1.id"),
66+
),
67+
},
68+
},
69+
},
70+
)
71+
}
72+
73+
func (s *DatasourcePrivateIPTestSuite) TestListPrivateIPsBySubnetID() {
74+
75+
resource.UnitTest(s.T(), resource.TestCase{
76+
PreventPostDestroyRefresh: true,
77+
Providers: s.Providers,
78+
Steps: []resource.TestStep{
79+
{
80+
ImportState: true,
81+
ImportStateVerify: true,
82+
Config: s.Config,
83+
},
84+
{
85+
Config: s.Config + `
86+
data "oci_core_private_ips" "testPrivateIPs" {
87+
subnet_id = "${oci_core_subnet.WebSubnetAD1.id}"
88+
}
89+
`,
90+
Check: resource.ComposeTestCheckFunc(
91+
resource.TestCheckResourceAttr(s.ResourceName, "private_ips.#", "2"),
92+
resource.TestCheckResourceAttrSet(s.ResourceName, "private_ips.0.id"),
93+
resource.TestCheckResourceAttrSet(s.ResourceName, "private_ips.1.id"),
94+
),
95+
},
96+
},
97+
},
98+
)
99+
}
100+
101+
func (s *DatasourcePrivateIPTestSuite) TestListPrivateIPsByIPAddress() {
102+
103+
resource.UnitTest(s.T(), resource.TestCase{
104+
PreventPostDestroyRefresh: true,
105+
Providers: s.Providers,
106+
Steps: []resource.TestStep{
107+
{
108+
ImportState: true,
109+
ImportStateVerify: true,
110+
Config: s.Config,
111+
},
112+
{
113+
Config: s.Config + `
114+
data "oci_core_private_ips" "testPrivateIPs" {
115+
ip_address = "10.0.1.23"
116+
subnet_id = "${oci_core_subnet.WebSubnetAD1.id}"
117+
}
118+
`,
119+
Check: resource.ComposeTestCheckFunc(
120+
resource.TestCheckResourceAttrSet(s.ResourceName, "private_ips.0.id"),
121+
resource.TestCheckResourceAttr(s.ResourceName, "private_ips.0.ip_address", "10.0.1.23"),
122+
resource.TestCheckResourceAttr(s.ResourceName, "private_ips.#", "1"),
123+
),
124+
},
125+
},
126+
},
127+
)
128+
}
129+
130+
func TestDatasourcePrivateIPTestSuite(t *testing.T) {
131+
suite.Run(t, new(DatasourcePrivateIPTestSuite))
132+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# oci\_core\_private_ips
2+
3+
Gets a list of private_ips.
4+
5+
## Example Usage
6+
7+
```
8+
data "oci_core_private_ips" "testPrivateIPs" {
9+
ip_address = "${var.ip_address}"
10+
subnet_id = "${var.subnet_id}"
11+
vnic_id = "${var.vnic_id}"
12+
}
13+
14+
```
15+
16+
## Description
17+
Lists the PrivateIp objects based on one of these filters:
18+
19+
- Subnet OCID.
20+
- VNIC OCID.
21+
- Both private IP address and subnet OCID: This lets
22+
you get a `privateIP` object based on its private IP
23+
address (for example, 10.0.3.3) and not its OCID.
24+
25+
If you're listing all the private IPs associated with a given subnet
26+
or VNIC, the response includes both primary and secondary private IPs.
27+
28+
## Argument Reference
29+
30+
The following arguments are supported:
31+
32+
* `ip_address` - (Optional) The private IP address of the `privateIp` object. Example: `10.0.3.3`
33+
* `subnet_id` - (Optional) The OCID of the subnet.
34+
* `vnic_id` - (Optional) The OCID of the VNIC.
35+
36+
37+
## Attributes Reference
38+
39+
The following attributes are exported:
40+
41+
* `private_ips` - The list of private_ips.
42+
43+
## PrivateIP Reference
44+
* `availability_domain` - The private IP's Availability Domain. Example: `Uocm:PHX-AD-1`
45+
* `compartment_id` - The OCID of the compartment containing the private IP.
46+
* `display_name` - A user-friendly name. Does not have to be unique, and it's changeable. Avoid entering confidential information.
47+
* `hostname_label` - The hostname for the private IP. Used for DNS. The value is the hostname portion of the private IP's fully qualified domain name (FQDN) (for example, `bminstance-1` in FQDN `bminstance-1.subnet123.vcn1.oraclevcn.com`). Must be unique across all VNICs in the subnet and comply with [RFC 952](https://tools.ietf.org/html/rfc952) and [RFC 1123](https://tools.ietf.org/html/rfc1123). For more information, see [DNS in Your Virtual Cloud Network](/Content/Network/Concepts/dns.htm). Example: `bminstance-1`
48+
* `id` - The private IP's Oracle ID (OCID).
49+
* `ip_address` - The private IP address of the `privateIp` object. The address is within the CIDR of the VNIC's subnet. Example: `10.0.3.3`
50+
* `is_primary` - Whether this private IP is the primary one on the VNIC. Primary private IPs are unassigned and deleted automatically when the VNIC is terminated. Example: `true`
51+
* `subnet_id` - The OCID of the subnet the VNIC is in.
52+
* `time_created` - The date and time the private IP was created, in the format defined by RFC3339. Example: `2016-08-25T21:10:29.600Z`
53+
* `vnic_id` - The OCID of the VNIC the private IP is assigned to. The VNIC and private IP must be in the same subnet.
54+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
### Authentication details
2+
export TF_VAR_tenancy_ocid="<tenancy OCID>"
3+
export TF_VAR_user_ocid="<user OCID>"
4+
export TF_VAR_fingerprint="<PEM key fingerprint>"
5+
export TF_VAR_private_key_path="<path to the private key that matches the fingerprint above>"
6+
7+
### Region
8+
export TF_VAR_region="<region in which to operate, example: us-ashburn-1, us-phoenix-1>"
9+
10+
### Compartment
11+
export TF_VAR_compartment_ocid="<compartment OCID>"
12+
13+
### Availability Domain
14+
#### Availability Domain represented as an integer [1-3]. Default value is 1 if env var is not set.
15+
export TF_VAR_AD=1
16+
17+
## Specific to this example
18+
### Choose a subnet that exists in the AD and compartment you are launching the instance in
19+
export TF_VAR_subnet_ocid="<subnet>"
20+
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
variable "tenancy_ocid" {}
2+
variable "user_ocid" {}
3+
variable "fingerprint" {}
4+
variable "private_key_path" {}
5+
variable "region" {}
6+
7+
variable "compartment_ocid" {}
8+
variable "ssh_public_key" {}
9+
variable "ssh_private_key" {}
10+
11+
variable "subnet_ocid" {}
12+
13+
# Choose an Availability Domain
14+
variable "AD" {
15+
default = "1"
16+
}
17+
18+
provider "oci" {
19+
tenancy_ocid = "${var.tenancy_ocid}"
20+
user_ocid = "${var.user_ocid}"
21+
fingerprint = "${var.fingerprint}"
22+
private_key_path = "${var.private_key_path}"
23+
region = "${var.region}"
24+
disable_auto_retries = true
25+
}
26+
27+
# Gets a list of Availability Domains
28+
data "oci_identity_availability_domains" "ADs" {
29+
compartment_id = "${var.tenancy_ocid}"
30+
}
31+
32+
# Gets the OCID of the OS image to use
33+
data "oci_core_images" "OLImageOCID" {
34+
compartment_id = "${var.compartment_ocid}"
35+
operating_system = "Oracle Linux"
36+
operating_system_version = "7.3"
37+
}
38+
39+
# Create Instance
40+
resource "oci_core_instance" "TFInstance1" {
41+
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.AD - 1],"name")}"
42+
compartment_id = "${var.compartment_ocid}"
43+
display_name = "TFInstance"
44+
hostname_label = "instance"
45+
image = "${lookup(data.oci_core_images.OLImageOCID.images[0], "id")}"
46+
shape = "VM.Standard1.2"
47+
subnet_id = "${var.subnet_ocid}"
48+
}
49+
50+
# Gets a list of VNIC attachments on the instance
51+
data "oci_core_vnic_attachments" "InstanceVnics" {
52+
compartment_id = "${var.compartment_ocid}"
53+
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.AD - 1],"name")}"
54+
instance_id = "${oci_core_instance.TFInstance1.id}"
55+
}
56+
57+
# Gets the OCID of the first (default) VNIC
58+
data "oci_core_vnic" "InstanceVnic" {
59+
vnic_id = "${lookup(data.oci_core_vnic_attachments.InstanceVnics.vnic_attachments[0],"vnic_id")}"
60+
}
61+
62+
# Create PrivateIP
63+
resource "oci_core_private_ip" "TFPrivateIP" {
64+
vnic_id = "${lookup(data.oci_core_vnic_attachments.InstanceVnics.vnic_attachments[0],"vnic_id")}"
65+
display_name = "someDisplayName"
66+
hostname_label = "somehostnamelabel"
67+
}
68+
69+
# List Private IPs
70+
data "oci_core_private_ips" "privateIpDatasource" {
71+
depends_on = ["oci_core_private_ip.TFPrivateIP"]
72+
vnic_id = "${oci_core_private_ip.TFPrivateIP.vnic_id}"
73+
}
74+
75+
output "privateIPs" {
76+
value = ["${data.oci_core_private_ips.privateIpDatasource.private_ips}"]
77+
}

0 commit comments

Comments
 (0)