Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reserved IP related resources and data source #830

Merged
merged 11 commits into from Jun 15, 2022
30 changes: 8 additions & 22 deletions digitalocean/datasource_digitalocean_floating_ip.go
Expand Up @@ -8,11 +8,12 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func dataSourceDigitalOceanFloatingIp() *schema.Resource {
func dataSourceDigitalOceanFloatingIP() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceDigitalOceanFloatingIpRead,
// TODO: Uncomment when dates for deprecation timeline are set.
// DeprecationMessage: "This data source is deprecated and will be removed in a future release. Please use digitalocean_reserved_ip instead.",
ReadContext: dataSourceDigitalOceanFloatingIPRead,
Schema: map[string]*schema.Schema{

"ip_address": {
Type: schema.TypeString,
Required: true,
Expand All @@ -39,27 +40,12 @@ func dataSourceDigitalOceanFloatingIp() *schema.Resource {
}
}

func dataSourceDigitalOceanFloatingIpRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*CombinedConfig).godoClient()

ipAddress := d.Get("ip_address").(string)

floatingIp, resp, err := client.FloatingIPs.Get(context.Background(), ipAddress)
func dataSourceDigitalOceanFloatingIPRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
err := dataSourceDigitalOceanReservedIPRead(ctx, d, meta)
if err != nil {
if resp != nil && resp.StatusCode == 404 {
return diag.Errorf("floating ip not found: %s", err)
}
return diag.Errorf("Error retrieving floating ip: %s", err)
}

d.SetId(floatingIp.IP)
d.Set("ip_address", floatingIp.IP)
d.Set("urn", floatingIp.URN())
d.Set("region", floatingIp.Region.Slug)

if floatingIp.Droplet != nil {
d.Set("droplet_id", floatingIp.Droplet.ID)
return err
}
reservedIPURNtoFloatingIPURN(d)

return nil
}
46 changes: 46 additions & 0 deletions digitalocean/datasource_digitalocean_reserved_ip.go
@@ -0,0 +1,46 @@
package digitalocean

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func dataSourceDigitalOceanReservedIP() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceDigitalOceanReservedIPRead,
Schema: map[string]*schema.Schema{
"ip_address": {
Type: schema.TypeString,
Required: true,
Description: "reserved ip address",
ValidateFunc: validation.NoZeroValues,
},
// computed attributes
"urn": {
Type: schema.TypeString,
Computed: true,
Description: "the uniform resource name for the reserved ip",
},
"region": {
Type: schema.TypeString,
Computed: true,
Description: "the region that the reserved ip is reserved to",
},
"droplet_id": {
Type: schema.TypeInt,
Computed: true,
Description: "the droplet id that the reserved ip has been assigned to.",
},
},
}
}

func dataSourceDigitalOceanReservedIPRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
ipAddress := d.Get("ip_address").(string)
d.SetId(ipAddress)

return resourceDigitalOceanReservedIPRead(ctx, d, meta)
}
108 changes: 108 additions & 0 deletions digitalocean/datasource_digitalocean_reserved_ip_test.go
@@ -0,0 +1,108 @@
package digitalocean

import (
"context"
"fmt"
"regexp"
"testing"

"github.com/digitalocean/godo"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestAccDataSourceDigitalOceanReservedIP_Basic(t *testing.T) {
var reservedIP godo.ReservedIP

expectedURNRegEx, _ := regexp.Compile(`do:reservedip:(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccCheckDataSourceDigitalOceanReservedIPConfig_Basic,
Check: resource.ComposeTestCheckFunc(
testAccCheckDataSourceDigitalOceanReservedIPExists("data.digitalocean_reserved_ip.foobar", &reservedIP),
resource.TestCheckResourceAttrSet(
"data.digitalocean_reserved_ip.foobar", "ip_address"),
resource.TestCheckResourceAttr(
"data.digitalocean_reserved_ip.foobar", "region", "nyc3"),
resource.TestMatchResourceAttr("data.digitalocean_reserved_ip.foobar", "urn", expectedURNRegEx),
),
},
},
})
}

func TestAccDataSourceDigitalOceanReservedIP_FindsFloatingIP(t *testing.T) {
var reservedIP godo.ReservedIP

expectedURNRegEx, _ := regexp.Compile(`do:reservedip:(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccCheckDataSourceDigitalOceanReservedIPConfig_FindsFloatingIP,
Check: resource.ComposeTestCheckFunc(
testAccCheckDataSourceDigitalOceanReservedIPExists("data.digitalocean_reserved_ip.foobar", &reservedIP),
resource.TestCheckResourceAttrSet(
"data.digitalocean_reserved_ip.foobar", "ip_address"),
resource.TestCheckResourceAttr(
"data.digitalocean_reserved_ip.foobar", "region", "nyc3"),
resource.TestMatchResourceAttr("data.digitalocean_reserved_ip.foobar", "urn", expectedURNRegEx),
),
},
},
})
}

func testAccCheckDataSourceDigitalOceanReservedIPExists(n string, reservedIP *godo.ReservedIP) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]

if !ok {
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No reserved IP ID is set")
}

client := testAccProvider.Meta().(*CombinedConfig).godoClient()

foundReservedIP, _, err := client.ReservedIPs.Get(context.Background(), rs.Primary.ID)

if err != nil {
return err
}

if foundReservedIP.IP != rs.Primary.ID {
return fmt.Errorf("reserved IP not found")
}

*reservedIP = *foundReservedIP

return nil
}
}

const testAccCheckDataSourceDigitalOceanReservedIPConfig_FindsFloatingIP = `
resource "digitalocean_floating_ip" "foo" {
region = "nyc3"
}

data "digitalocean_reserved_ip" "foobar" {
ip_address = digitalocean_floating_ip.foo.ip_address
}`

const testAccCheckDataSourceDigitalOceanReservedIPConfig_Basic = `
resource "digitalocean_reserved_ip" "foo" {
region = "nyc3"
}

data "digitalocean_reserved_ip" "foobar" {
ip_address = digitalocean_reserved_ip.foo.ip_address
}`
51 changes: 51 additions & 0 deletions digitalocean/import_digitalocean_reserved_ip_test.go
@@ -0,0 +1,51 @@
package digitalocean

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccDigitalOceanReservedIP_importBasicRegion(t *testing.T) {
resourceName := "digitalocean_reserved_ip.foobar"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviderFactories,
CheckDestroy: testAccCheckDigitalOceanReservedIPDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckDigitalOceanReservedIPConfig_region,
},

{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccDigitalOceanReservedIP_importBasicDroplet(t *testing.T) {
resourceName := "digitalocean_reserved_ip.foobar"
rInt := acctest.RandInt()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviderFactories,
CheckDestroy: testAccCheckDigitalOceanReservedIPDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckDigitalOceanReservedIPConfig_droplet(rInt),
},

{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
9 changes: 6 additions & 3 deletions digitalocean/provider.go
Expand Up @@ -61,7 +61,7 @@ func Provider() *schema.Provider {
"digitalocean_droplets": dataSourceDigitalOceanDroplets(),
"digitalocean_droplet_snapshot": dataSourceDigitalOceanDropletSnapshot(),
"digitalocean_firewall": dataSourceDigitalOceanFirewall(),
"digitalocean_floating_ip": dataSourceDigitalOceanFloatingIp(),
"digitalocean_floating_ip": dataSourceDigitalOceanFloatingIP(),
"digitalocean_image": dataSourceDigitalOceanImage(),
"digitalocean_images": dataSourceDigitalOceanImages(),
"digitalocean_kubernetes_cluster": dataSourceDigitalOceanKubernetesCluster(),
Expand All @@ -73,6 +73,7 @@ func Provider() *schema.Provider {
"digitalocean_records": dataSourceDigitalOceanRecords(),
"digitalocean_region": dataSourceDigitalOceanRegion(),
"digitalocean_regions": dataSourceDigitalOceanRegions(),
"digitalocean_reserved_ip": dataSourceDigitalOceanReservedIP(),
"digitalocean_sizes": dataSourceDigitalOceanSizes(),
"digitalocean_spaces_bucket": dataSourceDigitalOceanSpacesBucket(),
"digitalocean_spaces_buckets": dataSourceDigitalOceanSpacesBuckets(),
Expand Down Expand Up @@ -103,15 +104,17 @@ func Provider() *schema.Provider {
"digitalocean_droplet": resourceDigitalOceanDroplet(),
"digitalocean_droplet_snapshot": resourceDigitalOceanDropletSnapshot(),
"digitalocean_firewall": resourceDigitalOceanFirewall(),
"digitalocean_floating_ip": resourceDigitalOceanFloatingIp(),
"digitalocean_floating_ip_assignment": resourceDigitalOceanFloatingIpAssignment(),
"digitalocean_floating_ip": resourceDigitalOceanFloatingIP(),
"digitalocean_floating_ip_assignment": resourceDigitalOceanFloatingIPAssignment(),
"digitalocean_kubernetes_cluster": resourceDigitalOceanKubernetesCluster(),
"digitalocean_kubernetes_node_pool": resourceDigitalOceanKubernetesNodePool(),
"digitalocean_loadbalancer": resourceDigitalOceanLoadbalancer(),
"digitalocean_monitor_alert": resourceDigitalOceanMonitorAlert(),
"digitalocean_project": resourceDigitalOceanProject(),
"digitalocean_project_resources": resourceDigitalOceanProjectResources(),
"digitalocean_record": resourceDigitalOceanRecord(),
"digitalocean_reserved_ip": resourceDigitalOceanReservedIP(),
"digitalocean_reserved_ip_assignment": resourceDigitalOceanReservedIPAssignment(),
"digitalocean_spaces_bucket": resourceDigitalOceanBucket(),
"digitalocean_spaces_bucket_object": resourceDigitalOceanSpacesBucketObject(),
"digitalocean_spaces_bucket_policy": resourceDigitalOceanSpacesBucketPolicy(),
Expand Down